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. 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. 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 TCP or IPC 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. 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_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_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 -------- linkzmq:zmq[7] AUTHORS ------- This page was written by the 0MQ community. To make a change please read the 0MQ Contribution Policy at .