alworker:ブロードキャストメッセージ
AlWorker ブロードキャストメッセージ
require "al_worker_message"
イベントハンドラ間のブロードキャストメッセージ送信を実現します。
イベントをうけたいクライアントの数が動的に変わる場合に、1:n 通信をサポートします。
複数のクライアントがサーバーに対して接続されるが、クライアントの数は特定できない場合を想定しています。
使い方
送り側
@bc = BroadcastMessage.new() @bc.send( "message here" )
受け側
def tcp_a_recv( sock, param ) @bc.attach() message = @bc.receive() ensure @bc.detach() end
解説
@bc.receive()がコールされると動作を一旦停止し、メッセージが送られるのを待ちます。
@bc.send()をコールしてメッセージを送ると、@bc.receive()の返り値としてメッセージを受け取り、動作を再開します。
注意点・動作上の制限
- 受け側メソッドはreceive()メソッドで停止してしまうので、全体を止めないように _a_ をつけて、asynchronousにする必要があります。
- そのため非同期動作になるので、それが問題とならないようユーザプログラム側で配慮してください。
- IPCやTCPのハンドラ内で使うことが多いと思いますが、それらとは独立(疎結合)して動作しているので、相手からソケットクローズされた場合でも直後には検出できず次のイベント発生まで検出が遅延します。
- 送信頻度に比べ、受け側の接続/切断が頻繁に繰り返されるケースでは、イベント待ちキューが多く残りメモリ使用量が過大になる場合があるので、一定時間ごとにアイドルイベントを流すなどの工夫が必要になります。
サンプル
- bcm.rb
require "al_worker_message" require "al_worker_tcp" class AlWorker1 < AlWorker def initialize2() @bc = BroadcastMessage.new() @tcp = Tcp.new.run( self ) end def tcp_send( sock, param ) @bc.send( param[""] ) return true end def tcp_a_recv( sock, param ) @bc.attach() loop { message = @bc.receive() sock.puts message } ensure @bc.detach() end end AlWorker1.new.run
解説
実行するとデフォルトのTCPポート番号、1944番で接続を待ち受けます。
接続されたクライアントから、"recv"コマンドを受信するとメッセージ受信モードになり、メッセージの発生を待ちます。
別のクライアントから、"send <message>" コマンドを送信すると、メッセージ待ちモードのクライアントにメッセージを転送します。
送信側クライアント実行例
$telnet localhost 1944 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. send MESSAGE ONE send MESSAGE TWO
受信側クライアント実行例
$telnet localhost 1944 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. recv MESSAGE ONE MESSAGE TWO
alworker/ブロードキャストメッセージ.txt · 最終更新: 2020/08/27 15:03 by hirohito