Provided by: libzmq3-dev_4.3.2-2ubuntu1_amd64 bug

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.