Request, replyパターン
途中途中で更新していく。
前回のhello <-> world なパターンは絵にするとこんな感じ。最も単純かつよく使う Request/Reply パターンと呼ぶそうな。
その前に、衝撃を受けたので書いとく
- zmq_ctx_new()で生成したコンテキストはスレッドセーフ
- zmq_socket()で作ったソケットはスレッドアンセーフ
REQタイプ
本の説明はいきなり last-peer とか fair queue とか出てきて混乱したんだけど、実は単純な話で zmq ではソケットタイプによって使用方法にある程度縛りを設けて、通信をパターン化しているらしい。、rfc読んだら一発だった。
https://rfc.zeromq.org/spec:28/REQREP/
ZMQ_REQタイプはlock-step round-robin algorithmでリクエスト送信、そのリプライの受信を行う。クライアント側。単純なモデルで信頼性はそれほど必要としない、という前提。
- 任意数のREP or ROUTER に接続できる。
- 一度に1メッセージずつ送信-> 返信するモデル
送信パケットは
- 空フレームがデリミタとして追加される(? まだいまいちイメージできてないがダムフレームで送るのかな)
- 1つ以上のデータフレームでメッセージが構成される
- 相手がいないとかで送信できないときは、ブロックするかエラーを返す
- 送信できなかったメッセージも破棄されない
返信パケットは
- last-peer(つまりREQを送ったやつ)から到着したメッセージのみ受理
- それ以外のhostからのメッセージはしれっと捨てる
ZMQ_REP はいわゆるfair queue。つまり小さいほうから詰め込んでいく考え方。WFQじゃないのか。
REPタイプ
REQの受け側。リクエスト受信、そのリプライの送信を行う。
- 任意個のREQ or DEALER ピアに接続できる
- メッセージをフィルタや改変しない
- 一度に1メッセージずつ
受信(リクエスト)パケットは
- アドレスエンベロープは0以上のフレームからなりそれぞれが1つの識別子を持つ
- 空フレームがデリミタ
- 1つ以上のデータフレームでメッセージが構成される
受信パケットは
- fair-queueingで到着メッセージを受信
- アドレスエンベロープとかデリミタは削除してくれる
- アプリケーションには残りの実データが送られる
返信パケットは
- アプリケーションからの呼び出されて指定されるのを待つ
- アドレスエンベロープやらデリミタが追加される
- 発信元に送り返される
- 発信元が死んでいたりしたら、しれっと捨てるか、エラーを返す。
ついでなのでROUTER
REPの非同期版。DEALERクライアントとお話しするサーバのベースになることが多い。
明示的にアドレス使って、複数のピアと通信できる。
- 任意個のREQ, DEALER, ROUTERと接続できる
- 接続したピアに対して 1つのダブルキューを管理する
うーむ、ダブルキューてなに?
あー、理解。送信・受信、両方向キューですね。
- 自発的に送信するときも、リクエストもらうときも ダブルキューを確保する。
- 送信キューは接続がなくても破棄されない
- 受信キューは接続が切れたら破棄。
- 一意の "identity" binary string(?)とやらで各ダブルキューを選択
- Identity metadata property(?)とやらでピアが名乗る(識別される)ことが可能(なんのこっちゃい)
- 送受信キューサイズは実行時にリミットを与えられる
受信メッセージは
- fair queueing
- 到着メッセージは発信元ダブルキューの識別子が入ったフレームが最初に入る
送信メッセージは
- 送信メッセージの最初のフレームを破棄してこれをダブルキューの識別子とする- 送信キューに空きがあればそこに入れる
- キューがない、または空きがなければ、しれっと捨てるかエラー(設定による)
- ブロックしない