Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
ZMQ_SOCKET_MONITOR(3)		   0MQ Manual		   ZMQ_SOCKET_MONITOR(3)

NAME
     zmq_socket_monitor - monitor socket events

SYNOPSIS
     int zmq_socket_monitor (void *socket, char *endpoint, int events);

DESCRIPTION
     The  zmq_socket_monitor()	method	lets  an application thread track socket
     events (like connects) on a ZeroMQ socket. Each call to this method creates
     a ZMQ_PAIR socket and binds that to the specified	inproc://  endpoint.  To
     collect  the  socket  events, you must create your own ZMQ_PAIR socket, and
     connect that to the endpoint.

     Note that there is also a DRAFT  function	zmq_socket_monitor_versioned(3),
     which  allows to subscribe to events that provide more information. Calling
     zmq_socket_monitor is equivalent  to  calling  zmq_socket_monitor_versioned
     with  the	event_version  parameter  set  to 1, with the exception of error
     cases.

     The events argument is a bitmask of the socket events you wish to	monitor,
     see  Supported  events  below.  To  monitor all events, use the event value
     ZMQ_EVENT_ALL. NOTE: as new events are  added,  the  catch-all  value  will
     start  returning them. An application that relies on a strict and fixed se-
     quence of events must not use ZMQ_EVENT_ALL in order to guarantee	compati-
     bility with future versions.

     Each  event is sent as two frames. The first frame contains an event number
     (16 bits), and an event value (32 bits) that provides additional  data  ac-
     cording to the event number. The second frame contains a string that speci-
     fies the affected endpoint.

	 The _zmq_socket_monitor()_ method supports only connection-oriented
	 transports, that is, TCP, IPC, and TIPC.

SUPPORTED EVENTS
   ZMQ_EVENT_CONNECTED
     The  socket has successfully connected to a remote peer. The event value is
     the file descriptor (FD) of the underlying network socket.  Warning:  there
     is  no  guarantee that the FD is still valid by the time your code receives
     this event.

   ZMQ_EVENT_CONNECT_DELAYED
     A connect request on the socket is pending. The event value is unspecified.

   ZMQ_EVENT_CONNECT_RETRIED
     A connect request failed, and is now being retried. The event value is  the
     reconnect interval in milliseconds. Note that the reconnect interval is re-
     calculated at each retry.

   ZMQ_EVENT_LISTENING
     The  socket  was successfully bound to a network interface. The event value
     is the FD of the underlying network socket. Warning: there is no  guarantee
     that the FD is still valid by the time your code receives this event.

   ZMQ_EVENT_BIND_FAILED
     The  socket could not bind to a given interface. The event value is the er-
     rno generated by the system bind call.

   ZMQ_EVENT_ACCEPTED
     The socket has accepted a connection from a remote peer. The event value is
     the FD of the underlying network socket. Warning:	there  is  no  guarantee
     that the FD is still valid by the time your code receives this event.

   ZMQ_EVENT_ACCEPT_FAILED
     The socket has rejected a connection from a remote peer. The event value is
     the errno generated by the accept call.

   ZMQ_EVENT_CLOSED
     The  socket  was closed. The event value is the FD of the (now closed) net-
     work socket.

   ZMQ_EVENT_CLOSE_FAILED
     The socket close failed. The event value is the errno returned by the  sys-
     tem call. Note that this event occurs only on IPC transports.

   ZMQ_EVENT_DISCONNECTED
     The  socket was disconnected unexpectedly. The event value is the FD of the
     underlying network socket. Warning: this socket will be closed.

   ZMQ_EVENT_MONITOR_STOPPED
     Monitoring on this socket ended.

   ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
     Unspecified error during handshake. The event value is an errno.

   ZMQ_EVENT_HANDSHAKE_SUCCEEDED
     The ZMTP security mechanism handshake succeeded. The event value is unspec-
     ified.

   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
     The ZMTP security mechanism handshake failed due to some mechanism protocol
     error, either between the ZMTP mechanism peers, or  between  the  mechanism
     server  and  the ZAP handler. This indicates a configuration or implementa-
     tion error in either peer resp. the ZAP handler. The event value is one  of
     the    ZMQ_PROTOCOL_ERROR_*   values:   ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED
     ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND      ZMQ_PROTOCOL_ERROR_ZMTP_IN-
     VALID_SEQUENCE	ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE	ZMQ_PROTOCOL_ER-
     ROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED	    ZMQ_PROTOCOL_ERROR_ZMTP_MAL-
     FORMED_COMMAND_MESSAGE	 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
     ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 	ZMQ_PROTOCOL_ER-
     ROR_ZMTP_MALFORMED_COMMAND_ERROR	  ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COM-
     MAND_READY   ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME   ZMQ_PROTO-
     COL_ERROR_ZMTP_INVALID_METADATA	   ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
     ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH  ZMQ_PROTOCOL_ERROR_ZAP_UNSPECI-
     FIED  ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY ZMQ_PROTOCOL_ERROR_ZAP_BAD_RE-
     QUEST_ID	ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION    ZMQ_PROTOCOL_ERROR_ZAP_IN-
     VALID_STATUS_CODE ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA

   ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
     The ZMTP security mechanism handshake failed due to an authentication fail-
     ure.  The	event value is the status code returned by the ZAP handler (i.e.
     300, 400 or 500).

RETURN VALUE
     The zmq_socket_monitor() function returns a value of 0 or greater	if  suc-
     cessful.  Otherwise  it  returns -1 and sets errno to one of the values de-
     fined below.

ERRORS
     ETERM
	 The 0MQ context associated with the specified socket was terminated.

     EPROTONOSUPPORT
	 The requested transport protocol is not supported. Monitor sockets  are
	 required to use the inproc:// transport.

     EINVAL
	 The endpoint supplied is invalid.

EXAMPLE
     Monitoring client and server sockets.

	 //  Read one event off the monitor socket; return value and address
	 //  by reference, if not null, and event number by value. Returns -1
	 //  in case of error.

	 static int
	 get_monitor_event (void *monitor, int *value, char **address)
	 {
	     //  First frame in message contains event number and value
	     zmq_msg_t msg;
	     zmq_msg_init (&msg);
	     if (zmq_msg_recv (&msg, monitor, 0) == -1)
		 return -1;		 //  Interrupted, presumably
	     assert (zmq_msg_more (&msg));

	     uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
	     uint16_t event = *(uint16_t *) (data);
	     if (value)
		 *value = *(uint32_t *) (data + 2);

	     //  Second frame in message contains event address
	     zmq_msg_init (&msg);
	     if (zmq_msg_recv (&msg, monitor, 0) == -1)
		 return -1;		 //  Interrupted, presumably
	     assert (!zmq_msg_more (&msg));

	     if (address) {
		 uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
		 size_t size = zmq_msg_size (&msg);
		 *address = (char *) malloc (size + 1);
		 memcpy (*address, data, size);
		 (*address)[size] = 0;
	     }
	     return event;
	 }

	 int main (void)
	 {
	     void *ctx = zmq_ctx_new ();
	     assert (ctx);

	     //  We'll monitor these two sockets
	     void *client = zmq_socket (ctx, ZMQ_DEALER);
	     assert (client);
	     void *server = zmq_socket (ctx, ZMQ_DEALER);
	     assert (server);

	     //  Socket monitoring only works over inproc://
	     int rc = zmq_socket_monitor (client, "tcp://127.0.0.1:9999", 0);
	     assert (rc == -1);
	     assert (zmq_errno () == EPROTONOSUPPORT);

	     //  Monitor all events on client and server sockets
	     rc = zmq_socket_monitor (client, "inproc://monitor-client", ZMQ_EVENT_ALL);
	     assert (rc == 0);
	     rc = zmq_socket_monitor (server, "inproc://monitor-server", ZMQ_EVENT_ALL);
	     assert (rc == 0);

	     //  Create two sockets for collecting monitor events
	     void *client_mon = zmq_socket (ctx, ZMQ_PAIR);
	     assert (client_mon);
	     void *server_mon = zmq_socket (ctx, ZMQ_PAIR);
	     assert (server_mon);

	     //  Connect these to the inproc endpoints so they'll get events
	     rc = zmq_connect (client_mon, "inproc://monitor-client");
	     assert (rc == 0);
	     rc = zmq_connect (server_mon, "inproc://monitor-server");
	     assert (rc == 0);

	     //  Now do a basic ping test
	     rc = zmq_bind (server, "tcp://127.0.0.1:9998");
	     assert (rc == 0);
	     rc = zmq_connect (client, "tcp://127.0.0.1:9998");
	     assert (rc == 0);
	     bounce (client, server);

	     //  Close client and server
	     close_zero_linger (client);
	     close_zero_linger (server);

	     //  Now collect and check events from both sockets
	     int event = get_monitor_event (client_mon, NULL, NULL);
	     if (event == ZMQ_EVENT_CONNECT_DELAYED)
		 event = get_monitor_event (client_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_CONNECTED);
	     event = get_monitor_event (client_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
	     event = get_monitor_event (client_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_MONITOR_STOPPED);

	     //  This is the flow of server events
	     event = get_monitor_event (server_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_LISTENING);
	     event = get_monitor_event (server_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_ACCEPTED);
	     event = get_monitor_event (server_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
	     event = get_monitor_event (server_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_CLOSED);
	     event = get_monitor_event (server_mon, NULL, NULL);
	     assert (event == ZMQ_EVENT_MONITOR_STOPPED);

	     //  Close down the sockets
	     close_zero_linger (client_mon);
	     close_zero_linger (server_mon);
	     zmq_ctx_term (ctx);

	     return 0 ;
	 }

SEE ALSO
     zmq(7)

AUTHORS
     This  page  was  written by the 0MQ community. To make a change please read
     the 0MQ Contribution Policy at http://www.zeromq.org/docs:contributing.

0MQ 4.3.5			   10/09/2023		   ZMQ_SOCKET_MONITOR(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=zmq_socket_monitor&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help