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

FreeBSD Manual Pages

  
 
  

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 sequence of events must not use ZMQ_EVENT_ALL in order	to
       guarantee compatibility 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 according to the event number. The second frame contains a string
       that specifies 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 recalculated	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
       errno 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)
       network socket.

   ZMQ_EVENT_CLOSE_FAILED
       The socket close	failed.	The event value	is the errno returned by the
       system 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
       unspecified.

   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
       implementation 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_INVALID_SEQUENCE
       ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE
       ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED
       ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE
       ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
       ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE
       ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
       ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY
       ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME
       ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA
       ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
       ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH
       ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED
       ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
       ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
       ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
       ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
       ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA

   ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
       The ZMTP	security mechanism handshake failed due	to an authentication
       failure.	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
       successful. Otherwise it	returns	-1 and sets errno to one of the	values
       defined 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+14.3.quarterly>

home | help