ZeroMQのzmq_socket_monitor(3)の挙動を調べた

ZeroMQのzmq_socket_monitor(3)の挙動を調べてみました。 bindするソケットとconnectするソケットを用意し、以下の順に処理して zmq_socket_monitor(3)でどのようなイベントが通知されるか確認しました。

  1. create (bind/connect socket)
  2. bind
  3. connect
  4. disconnect
  5. close (connect socket)
  6. create (connect socket)
  7. connect
  8. unbind
  9. close (bind socket)

上記の処理を1秒間隔で行い、イベントの出力を確認します。 使用したソースコードこちらに載せました。

bind側の出力

vagrant@vagrant-ubuntu-trusty-64:~$ ./a.out bind tcp://0.0.0.0:2551
[0.000] [main] Create...
[1.000] [main] Bind...
[1.010] [event] number: 8, value: 12, address: tcp://0.0.0.0:2551
[2.011] [event] number: 32, value: 13, address: tcp://0.0.0.0:2551
[4.014] [event] number: 512, value: 13, address: tcp://0.0.0.0:2551
[6.019] [event] number: 32, value: 13, address: tcp://0.0.0.0:2551
[7.001] [main] Unbind...
[7.009] [event] number: 128, value: 12, address: tcp://0.0.0.0:2551
[8.003] [main] Close...
[8.004] [event] number: 1024, value: 0, address:
[9.004] [main] Finish...

connect側の出力

vagrant@vagrant-ubuntu-trusty-64:~$ ./a.out connect tcp://192.168.0.1:2551
[0.000] [main] Create...
[2.000] [main] Connect...
[2.003] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[2.004] [event] number: 1, value: 12, address: tcp://192.168.0.1:2551
[3.002] [main] Disconnect...
[4.005] [main] Close...
[4.006] [event] number: 1024, value: 0, address:
[5.012] [main] Create...
[6.014] [main] Connect...
[6.015] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[6.016] [event] number: 1, value: 11, address: tcp://192.168.0.1:2551
[8.013] [event] number: 512, value: 11, address: tcp://192.168.0.1:2551
[8.014] [event] number: 4, value: 183, address: tcp://192.168.0.1:2551
[8.196] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[8.197] [event] number: 128, value: 11, address: tcp://192.168.0.1:2551
[8.197] [event] number: 4, value: 125, address: tcp://192.168.0.1:2551
[8.316] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[8.317] [event] number: 128, value: 11, address: tcp://192.168.0.1:2551
[8.317] [event] number: 4, value: 141, address: tcp://192.168.0.1:2551
[8.466] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[8.466] [event] number: 128, value: 11, address: tcp://192.168.0.1:2551
[8.467] [event] number: 4, value: 186, address: tcp://192.168.0.1:2551
[8.652] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[8.653] [event] number: 128, value: 11, address: tcp://192.168.0.1:2551
[8.654] [event] number: 4, value: 197, address: tcp://192.168.0.1:2551
[8.848] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[8.849] [event] number: 128, value: 11, address: tcp://192.168.0.1:2551
[8.849] [event] number: 4, value: 110, address: tcp://192.168.0.1:2551
[8.957] [event] number: 2, value: 115, address: tcp://192.168.0.1:2551
[8.958] [event] number: 128, value: 11, address: tcp://192.168.0.1:2551
[8.959] [event] number: 4, value: 138, address: tcp://192.168.0.1:2551
[9.015] [main] Close...
[9.015] [main] Finish...

一番左側の列は経過時間を表しています。 numberはZeroMQで定義されているイベント番号で、以下のようになっています。

/*  Socket transport events (tcp and ipc only)                                */
#define ZMQ_EVENT_CONNECTED 1
#define ZMQ_EVENT_CONNECT_DELAYED 2
#define ZMQ_EVENT_CONNECT_RETRIED 4

#define ZMQ_EVENT_LISTENING 8
#define ZMQ_EVENT_BIND_FAILED 16

#define ZMQ_EVENT_ACCEPTED 32
#define ZMQ_EVENT_ACCEPT_FAILED 64

#define ZMQ_EVENT_CLOSED 128
#define ZMQ_EVENT_CLOSE_FAILED 256
#define ZMQ_EVENT_DISCONNECTED 512
#define ZMQ_EVENT_MONITOR_STOPPED 1024

この結果からわかることは、

  • bindした直後にbind側でZMQ_EVENT_LISTENINGが通知される
  • connectした直後にbind側でZMQ_EVENT_ACCEPTED、connect側でZMQ_EVENT_CONNECT_DELAYEDZMQ_EVENT_CONNECTEDが通知される
  • disconnectしてもbind側、connect側共に何も通知されない
  • unbindするとbind側にはZMQ_EVENT_CLOSEDが通知されるが、connect側には何も通知されない
  • connect側をcloseするとbind側にZMQ_EVENT_DISCONNECTEDが通知される
  • bind側をcloseするとconnect側にZMQ_EVENT_DISCONNECTEDが通知され、connect側は再接続を試みる
  • connect側が再接続を試みている間は、ZMQ_EVENT_CLOSEDZMQ_EVENT_CONNECT_RETRIEDZMQ_EVENT_CONNECT_DELAYEDが通知され続ける
  • ソケットをcloseすると、ZMQ_EVENT_MONITOR_STOPPEDが通知される

ちなみに、プロセスを強制的に落とした場合はcloseしたときと同じ挙動になり、 ZMQ_EVENT_DISCONNECTEDが通知されます。

今回は通知するイベントをZMQ_EVENT_ALLにしましたが、 実際に使うときには適切なイベントを選択して通知した方が良いかと思います。

※ZeroMQ v4.2.1を使用