'\" t .\" Title: zmq_socket_monitor .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 10/23/2023 .\" Manual: 0MQ Manual .\" Source: 0MQ 4.3.5 .\" Language: English .\" .TH "ZMQ_SOCKET_MONITOR" "3" "10/23/2023" "0MQ 4\&.3\&.5" "0MQ Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" zmq_socket_monitor \- monitor socket events .SH "SYNOPSIS" .sp \fBint zmq_socket_monitor (void \fR\fB\fI*socket\fR\fR\fB, char \fR\fB\fI*endpoint\fR\fR\fB, int \fR\fB\fIevents\fR\fR\fB);\fR .SH "DESCRIPTION" .sp The \fIzmq_socket_monitor()\fR method lets an application thread track socket events (like connects) on a ZeroMQ socket\&. Each call to this method creates a \fIZMQ_PAIR\fR socket and binds that to the specified inproc:// \fIendpoint\fR\&. To collect the socket events, you must create your own \fIZMQ_PAIR\fR socket, and connect that to the endpoint\&. .sp Note that there is also a DRAFT function \fBzmq_socket_monitor_versioned\fR(3), which allows to subscribe to events that provide more information\&. Calling zmq_socket_monitor is equivalent to calling \fIzmq_socket_monitor_versioned\fR with the \fIevent_version\fR parameter set to 1, with the exception of error cases\&. .sp The \fIevents\fR argument is a bitmask of the socket events you wish to monitor, see \fISupported events\fR 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\&. .sp 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\&. .sp .if n \{\ .RS 4 .\} .nf The _zmq_socket_monitor()_ method supports only connection\-oriented transports, that is, TCP, IPC, and TIPC\&. .fi .if n \{\ .RE .\} .SH "SUPPORTED EVENTS" .SS "ZMQ_EVENT_CONNECTED" .sp 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\&. .SS "ZMQ_EVENT_CONNECT_DELAYED" .sp A connect request on the socket is pending\&. The event value is unspecified\&. .SS "ZMQ_EVENT_CONNECT_RETRIED" .sp 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\&. .SS "ZMQ_EVENT_LISTENING" .sp 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\&. .SS "ZMQ_EVENT_BIND_FAILED" .sp The socket could not bind to a given interface\&. The event value is the errno generated by the system bind call\&. .SS "ZMQ_EVENT_ACCEPTED" .sp 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\&. .SS "ZMQ_EVENT_ACCEPT_FAILED" .sp The socket has rejected a connection from a remote peer\&. The event value is the errno generated by the accept call\&. .SS "ZMQ_EVENT_CLOSED" .sp The socket was closed\&. The event value is the FD of the (now closed) network socket\&. .SS "ZMQ_EVENT_CLOSE_FAILED" .sp The socket close failed\&. The event value is the errno returned by the system call\&. Note that this event occurs only on IPC transports\&. .SS "ZMQ_EVENT_DISCONNECTED" .sp The socket was disconnected unexpectedly\&. The event value is the FD of the underlying network socket\&. Warning: this socket will be closed\&. .SS "ZMQ_EVENT_MONITOR_STOPPED" .sp Monitoring on this socket ended\&. .SS "ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL" .sp Unspecified error during handshake\&. The event value is an errno\&. .SS "ZMQ_EVENT_HANDSHAKE_SUCCEEDED" .sp The ZMTP security mechanism handshake succeeded\&. The event value is unspecified\&. .SS "ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL" .sp 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 .SS "ZMQ_EVENT_HANDSHAKE_FAILED_AUTH" .sp 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)\&. .SH "RETURN VALUE" .sp The \fIzmq_socket_monitor()\fR function returns a value of 0 or greater if successful\&. Otherwise it returns \-1 and sets \fIerrno\fR to one of the values defined below\&. .SH "ERRORS" .PP \fBETERM\fR .RS 4 The 0MQ \fIcontext\fR associated with the specified \fIsocket\fR was terminated\&. .RE .PP \fBEPROTONOSUPPORT\fR .RS 4 The requested \fItransport\fR protocol is not supported\&. Monitor sockets are required to use the inproc:// transport\&. .RE .PP \fBEINVAL\fR .RS 4 The endpoint supplied is invalid\&. .RE .SH "EXAMPLE" .PP \fBMonitoring client and server sockets\fR. .sp .if n \{\ .RS 4 .\} .nf // 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\*(Aqll 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\*(Aqll 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 ; } .fi .if n \{\ .RE .\} .sp .SH "SEE ALSO" .sp \fBzmq\fR(7) .SH "AUTHORS" .sp This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&.