zmq_socket_monitor.txt 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. zmq_socket_monitor(3)
  2. =====================
  3. NAME
  4. ----
  5. zmq_socket_monitor - monitor socket events
  6. SYNOPSIS
  7. --------
  8. *int zmq_socket_monitor (void '*socket', char '*endpoint', int 'events');*
  9. DESCRIPTION
  10. -----------
  11. The _zmq_socket_monitor()_ method lets an application thread track
  12. socket events (like connects) on a ZeroMQ socket. Each call to this
  13. method creates a 'ZMQ_PAIR' socket and binds that to the specified
  14. inproc:// 'endpoint'. To collect the socket events, you must create
  15. your own 'ZMQ_PAIR' socket, and connect that to the endpoint.
  16. Note that there is also a DRAFT function linkzmq:zmq_socket_monitor_versioned[3],
  17. which allows to subscribe to events that provide more information.
  18. Calling zmq_socket_monitor is equivalent to calling 'zmq_socket_monitor_versioned'
  19. with the 'event_version' parameter set to 1, with the exception of error cases.
  20. The 'events' argument is a bitmask of the socket events you wish to
  21. monitor, see 'Supported events' below. To monitor all events, use the
  22. event value ZMQ_EVENT_ALL. NOTE: as new events are added, the catch-all
  23. value will start returning them. An application that relies on a strict
  24. and fixed sequence of events must not use ZMQ_EVENT_ALL in order to
  25. guarantee compatibility with future versions.
  26. Each event is sent as two frames. The first frame contains an event
  27. number (16 bits), and an event value (32 bits) that provides additional
  28. data according to the event number. The second frame contains a string
  29. that specifies the affected endpoint.
  30. ----
  31. The _zmq_socket_monitor()_ method supports only connection-oriented
  32. transports, that is, TCP, IPC, and TIPC.
  33. ----
  34. Supported events
  35. ----------------
  36. ZMQ_EVENT_CONNECTED
  37. ~~~~~~~~~~~~~~~~~~~
  38. The socket has successfully connected to a remote peer. The event value
  39. is the file descriptor (FD) of the underlying network socket. Warning:
  40. there is no guarantee that the FD is still valid by the time your code
  41. receives this event.
  42. ZMQ_EVENT_CONNECT_DELAYED
  43. ~~~~~~~~~~~~~~~~~~~~~~~~~
  44. A connect request on the socket is pending. The event value is unspecified.
  45. ZMQ_EVENT_CONNECT_RETRIED
  46. ~~~~~~~~~~~~~~~~~~~~~~~~~
  47. A connect request failed, and is now being retried. The event value is the
  48. reconnect interval in milliseconds. Note that the reconnect interval is
  49. recalculated at each retry.
  50. ZMQ_EVENT_LISTENING
  51. ~~~~~~~~~~~~~~~~~~~
  52. The socket was successfully bound to a network interface. The event value
  53. is the FD of the underlying network socket. Warning: there is no guarantee
  54. that the FD is still valid by the time your code receives this event.
  55. ZMQ_EVENT_BIND_FAILED
  56. ~~~~~~~~~~~~~~~~~~~~~
  57. The socket could not bind to a given interface. The event value is the
  58. errno generated by the system bind call.
  59. ZMQ_EVENT_ACCEPTED
  60. ~~~~~~~~~~~~~~~~~~
  61. The socket has accepted a connection from a remote peer. The event value is
  62. the FD of the underlying network socket. Warning: there is no guarantee that
  63. the FD is still valid by the time your code receives this event.
  64. ZMQ_EVENT_ACCEPT_FAILED
  65. ~~~~~~~~~~~~~~~~~~~~~~~
  66. The socket has rejected a connection from a remote peer. The event value is
  67. the errno generated by the accept call.
  68. ZMQ_EVENT_CLOSED
  69. ~~~~~~~~~~~~~~~~
  70. The socket was closed. The event value is the FD of the (now closed) network
  71. socket.
  72. ZMQ_EVENT_CLOSE_FAILED
  73. ~~~~~~~~~~~~~~~~~~~~~~
  74. The socket close failed. The event value is the errno returned by the system
  75. call. Note that this event occurs only on IPC transports.
  76. ZMQ_EVENT_DISCONNECTED
  77. ~~~~~~~~~~~~~~~~~~~~~~
  78. The socket was disconnected unexpectedly. The event value is the FD of the
  79. underlying network socket. Warning: this socket will be closed.
  80. ZMQ_EVENT_MONITOR_STOPPED
  81. ~~~~~~~~~~~~~~~~~~~~~~~~~
  82. Monitoring on this socket ended.
  83. ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
  84. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  85. Unspecified error during handshake.
  86. The event value is an errno.
  87. ZMQ_EVENT_HANDSHAKE_SUCCEEDED
  88. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  89. The ZMTP security mechanism handshake succeeded.
  90. The event value is unspecified.
  91. ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
  92. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  93. The ZMTP security mechanism handshake failed due to some mechanism protocol
  94. error, either between the ZMTP mechanism peers, or between the mechanism
  95. server and the ZAP handler. This indicates a configuration or implementation
  96. error in either peer resp. the ZAP handler.
  97. The event value is one of the ZMQ_PROTOCOL_ERROR_* values:
  98. ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED
  99. ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
  100. ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE
  101. ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE
  102. ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED
  103. ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE
  104. ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
  105. ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE
  106. ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
  107. ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY
  108. ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME
  109. ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA
  110. ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
  111. ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH
  112. ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED
  113. ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
  114. ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
  115. ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
  116. ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
  117. ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA
  118. ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
  119. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  120. The ZMTP security mechanism handshake failed due to an authentication failure.
  121. The event value is the status code returned by the ZAP handler (i.e. 300,
  122. 400 or 500).
  123. RETURN VALUE
  124. ------------
  125. The _zmq_socket_monitor()_ function returns a value of 0 or greater if
  126. successful. Otherwise it returns `-1` and sets 'errno' to one of the values
  127. defined below.
  128. ERRORS
  129. ------
  130. *ETERM*::
  131. The 0MQ 'context' associated with the specified 'socket' was terminated.
  132. *EPROTONOSUPPORT*::
  133. The requested 'transport' protocol is not supported. Monitor sockets are
  134. required to use the inproc:// transport.
  135. *EINVAL*::
  136. The endpoint supplied is invalid.
  137. EXAMPLE
  138. -------
  139. .Monitoring client and server sockets
  140. ----
  141. // Read one event off the monitor socket; return value and address
  142. // by reference, if not null, and event number by value. Returns -1
  143. // in case of error.
  144. static int
  145. get_monitor_event (void *monitor, int *value, char **address)
  146. {
  147. // First frame in message contains event number and value
  148. zmq_msg_t msg;
  149. zmq_msg_init (&msg);
  150. if (zmq_msg_recv (&msg, monitor, 0) == -1)
  151. return -1; // Interrupted, presumably
  152. assert (zmq_msg_more (&msg));
  153. uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
  154. uint16_t event = *(uint16_t *) (data);
  155. if (value)
  156. *value = *(uint32_t *) (data + 2);
  157. // Second frame in message contains event address
  158. zmq_msg_init (&msg);
  159. if (zmq_msg_recv (&msg, monitor, 0) == -1)
  160. return -1; // Interrupted, presumably
  161. assert (!zmq_msg_more (&msg));
  162. if (address) {
  163. uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
  164. size_t size = zmq_msg_size (&msg);
  165. *address = (char *) malloc (size + 1);
  166. memcpy (*address, data, size);
  167. (*address)[size] = 0;
  168. }
  169. return event;
  170. }
  171. int main (void)
  172. {
  173. void *ctx = zmq_ctx_new ();
  174. assert (ctx);
  175. // We'll monitor these two sockets
  176. void *client = zmq_socket (ctx, ZMQ_DEALER);
  177. assert (client);
  178. void *server = zmq_socket (ctx, ZMQ_DEALER);
  179. assert (server);
  180. // Socket monitoring only works over inproc://
  181. int rc = zmq_socket_monitor (client, "tcp://127.0.0.1:9999", 0);
  182. assert (rc == -1);
  183. assert (zmq_errno () == EPROTONOSUPPORT);
  184. // Monitor all events on client and server sockets
  185. rc = zmq_socket_monitor (client, "inproc://monitor-client", ZMQ_EVENT_ALL);
  186. assert (rc == 0);
  187. rc = zmq_socket_monitor (server, "inproc://monitor-server", ZMQ_EVENT_ALL);
  188. assert (rc == 0);
  189. // Create two sockets for collecting monitor events
  190. void *client_mon = zmq_socket (ctx, ZMQ_PAIR);
  191. assert (client_mon);
  192. void *server_mon = zmq_socket (ctx, ZMQ_PAIR);
  193. assert (server_mon);
  194. // Connect these to the inproc endpoints so they'll get events
  195. rc = zmq_connect (client_mon, "inproc://monitor-client");
  196. assert (rc == 0);
  197. rc = zmq_connect (server_mon, "inproc://monitor-server");
  198. assert (rc == 0);
  199. // Now do a basic ping test
  200. rc = zmq_bind (server, "tcp://127.0.0.1:9998");
  201. assert (rc == 0);
  202. rc = zmq_connect (client, "tcp://127.0.0.1:9998");
  203. assert (rc == 0);
  204. bounce (client, server);
  205. // Close client and server
  206. close_zero_linger (client);
  207. close_zero_linger (server);
  208. // Now collect and check events from both sockets
  209. int event = get_monitor_event (client_mon, NULL, NULL);
  210. if (event == ZMQ_EVENT_CONNECT_DELAYED)
  211. event = get_monitor_event (client_mon, NULL, NULL);
  212. assert (event == ZMQ_EVENT_CONNECTED);
  213. event = get_monitor_event (client_mon, NULL, NULL);
  214. assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
  215. event = get_monitor_event (client_mon, NULL, NULL);
  216. assert (event == ZMQ_EVENT_MONITOR_STOPPED);
  217. // This is the flow of server events
  218. event = get_monitor_event (server_mon, NULL, NULL);
  219. assert (event == ZMQ_EVENT_LISTENING);
  220. event = get_monitor_event (server_mon, NULL, NULL);
  221. assert (event == ZMQ_EVENT_ACCEPTED);
  222. event = get_monitor_event (server_mon, NULL, NULL);
  223. assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
  224. event = get_monitor_event (server_mon, NULL, NULL);
  225. assert (event == ZMQ_EVENT_CLOSED);
  226. event = get_monitor_event (server_mon, NULL, NULL);
  227. assert (event == ZMQ_EVENT_MONITOR_STOPPED);
  228. // Close down the sockets
  229. close_zero_linger (client_mon);
  230. close_zero_linger (server_mon);
  231. zmq_ctx_term (ctx);
  232. return 0 ;
  233. }
  234. ----
  235. SEE ALSO
  236. --------
  237. linkzmq:zmq[7]
  238. AUTHORS
  239. -------
  240. This page was written by the 0MQ community. To make a change please
  241. read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.