1ZMQ_SOCKET_MONITOR(3) 0MQ Manual ZMQ_SOCKET_MONITOR(3)
2
3
4
6 zmq_socket_monitor - monitor socket events
7
9 int zmq_socket_monitor (void *socket, char *endpoint, int events);
10
12 The zmq_socket_monitor() method lets an application thread track socket
13 events (like connects) on a ZeroMQ socket. Each call to this method
14 creates a ZMQ_PAIR socket and binds that to the specified inproc://
15 endpoint. To collect the socket events, you must create your own
16 ZMQ_PAIR socket, and connect that to the endpoint.
17
18 Note that there is also a DRAFT function
19 zmq_socket_monitor_versioned(3), which allows to subscribe to events
20 that provide more information. Calling zmq_socket_monitor is equivalent
21 to calling zmq_socket_monitor_versioned with the event_version
22 parameter set to 1, with the exception of error cases.
23
24 The events argument is a bitmask of the socket events you wish to
25 monitor, see Supported events below. To monitor all events, use the
26 event value ZMQ_EVENT_ALL. NOTE: as new events are added, the catch-all
27 value will start returning them. An application that relies on a strict
28 and fixed sequence of events must not use ZMQ_EVENT_ALL in order to
29 guarantee compatibility with future versions.
30
31 Each event is sent as two frames. The first frame contains an event
32 number (16 bits), and an event value (32 bits) that provides additional
33 data according to the event number. The second frame contains a string
34 that specifies the affected endpoint.
35
36 The _zmq_socket_monitor()_ method supports only connection-oriented
37 transports, that is, TCP, IPC, and TIPC.
38
40 ZMQ_EVENT_CONNECTED
41 The socket has successfully connected to a remote peer. The event value
42 is the file descriptor (FD) of the underlying network socket. Warning:
43 there is no guarantee that the FD is still valid by the time your code
44 receives this event.
45
46 ZMQ_EVENT_CONNECT_DELAYED
47 A connect request on the socket is pending. The event value is
48 unspecified.
49
50 ZMQ_EVENT_CONNECT_RETRIED
51 A connect request failed, and is now being retried. The event value is
52 the reconnect interval in milliseconds. Note that the reconnect
53 interval is recalculated at each retry.
54
55 ZMQ_EVENT_LISTENING
56 The socket was successfully bound to a network interface. The event
57 value is the FD of the underlying network socket. Warning: there is no
58 guarantee that the FD is still valid by the time your code receives
59 this event.
60
61 ZMQ_EVENT_BIND_FAILED
62 The socket could not bind to a given interface. The event value is the
63 errno generated by the system bind call.
64
65 ZMQ_EVENT_ACCEPTED
66 The socket has accepted a connection from a remote peer. The event
67 value is the FD of the underlying network socket. Warning: there is no
68 guarantee that the FD is still valid by the time your code receives
69 this event.
70
71 ZMQ_EVENT_ACCEPT_FAILED
72 The socket has rejected a connection from a remote peer. The event
73 value is the errno generated by the accept call.
74
75 ZMQ_EVENT_CLOSED
76 The socket was closed. The event value is the FD of the (now closed)
77 network socket.
78
79 ZMQ_EVENT_CLOSE_FAILED
80 The socket close failed. The event value is the errno returned by the
81 system call. Note that this event occurs only on IPC transports.
82
83 ZMQ_EVENT_DISCONNECTED
84 The socket was disconnected unexpectedly. The event value is the FD of
85 the underlying network socket. Warning: this socket will be closed.
86
87 ZMQ_EVENT_MONITOR_STOPPED
88 Monitoring on this socket ended.
89
90 ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
91 Unspecified error during handshake. The event value is an errno.
92
93 ZMQ_EVENT_HANDSHAKE_SUCCEEDED
94 The ZMTP security mechanism handshake succeeded. The event value is
95 unspecified.
96
97 ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
98 The ZMTP security mechanism handshake failed due to some mechanism
99 protocol error, either between the ZMTP mechanism peers, or between the
100 mechanism server and the ZAP handler. This indicates a configuration or
101 implementation error in either peer resp. the ZAP handler. The event
102 value is one of the ZMQ_PROTOCOL_ERROR_* values:
103 ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED
104 ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
105 ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE
106 ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE
107 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED
108 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE
109 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
110 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE
111 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
112 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY
113 ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME
114 ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA
115 ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
116 ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH
117 ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED
118 ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
119 ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
120 ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
121 ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
122 ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA
123
124 ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
125 The ZMTP security mechanism handshake failed due to an authentication
126 failure. The event value is the status code returned by the ZAP handler
127 (i.e. 300, 400 or 500).
128
130 The zmq_socket_monitor() function returns a value of 0 or greater if
131 successful. Otherwise it returns -1 and sets errno to one of the values
132 defined below.
133
135 ETERM
136 The 0MQ context associated with the specified socket was
137 terminated.
138
139 EPROTONOSUPPORT
140 The requested transport protocol is not supported. Monitor sockets
141 are required to use the inproc:// transport.
142
143 EINVAL
144 The endpoint supplied is invalid.
145
147 Monitoring client and server sockets.
148
149 // Read one event off the monitor socket; return value and address
150 // by reference, if not null, and event number by value. Returns -1
151 // in case of error.
152
153 static int
154 get_monitor_event (void *monitor, int *value, char **address)
155 {
156 // First frame in message contains event number and value
157 zmq_msg_t msg;
158 zmq_msg_init (&msg);
159 if (zmq_msg_recv (&msg, monitor, 0) == -1)
160 return -1; // Interrupted, presumably
161 assert (zmq_msg_more (&msg));
162
163 uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
164 uint16_t event = *(uint16_t *) (data);
165 if (value)
166 *value = *(uint32_t *) (data + 2);
167
168 // Second frame in message contains event address
169 zmq_msg_init (&msg);
170 if (zmq_msg_recv (&msg, monitor, 0) == -1)
171 return -1; // Interrupted, presumably
172 assert (!zmq_msg_more (&msg));
173
174 if (address) {
175 uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
176 size_t size = zmq_msg_size (&msg);
177 *address = (char *) malloc (size + 1);
178 memcpy (*address, data, size);
179 (*address)[size] = 0;
180 }
181 return event;
182 }
183
184 int main (void)
185 {
186 void *ctx = zmq_ctx_new ();
187 assert (ctx);
188
189 // We'll monitor these two sockets
190 void *client = zmq_socket (ctx, ZMQ_DEALER);
191 assert (client);
192 void *server = zmq_socket (ctx, ZMQ_DEALER);
193 assert (server);
194
195 // Socket monitoring only works over inproc://
196 int rc = zmq_socket_monitor (client, "tcp://127.0.0.1:9999", 0);
197 assert (rc == -1);
198 assert (zmq_errno () == EPROTONOSUPPORT);
199
200 // Monitor all events on client and server sockets
201 rc = zmq_socket_monitor (client, "inproc://monitor-client", ZMQ_EVENT_ALL);
202 assert (rc == 0);
203 rc = zmq_socket_monitor (server, "inproc://monitor-server", ZMQ_EVENT_ALL);
204 assert (rc == 0);
205
206 // Create two sockets for collecting monitor events
207 void *client_mon = zmq_socket (ctx, ZMQ_PAIR);
208 assert (client_mon);
209 void *server_mon = zmq_socket (ctx, ZMQ_PAIR);
210 assert (server_mon);
211
212 // Connect these to the inproc endpoints so they'll get events
213 rc = zmq_connect (client_mon, "inproc://monitor-client");
214 assert (rc == 0);
215 rc = zmq_connect (server_mon, "inproc://monitor-server");
216 assert (rc == 0);
217
218 // Now do a basic ping test
219 rc = zmq_bind (server, "tcp://127.0.0.1:9998");
220 assert (rc == 0);
221 rc = zmq_connect (client, "tcp://127.0.0.1:9998");
222 assert (rc == 0);
223 bounce (client, server);
224
225 // Close client and server
226 close_zero_linger (client);
227 close_zero_linger (server);
228
229 // Now collect and check events from both sockets
230 int event = get_monitor_event (client_mon, NULL, NULL);
231 if (event == ZMQ_EVENT_CONNECT_DELAYED)
232 event = get_monitor_event (client_mon, NULL, NULL);
233 assert (event == ZMQ_EVENT_CONNECTED);
234 event = get_monitor_event (client_mon, NULL, NULL);
235 assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
236 event = get_monitor_event (client_mon, NULL, NULL);
237 assert (event == ZMQ_EVENT_MONITOR_STOPPED);
238
239 // This is the flow of server events
240 event = get_monitor_event (server_mon, NULL, NULL);
241 assert (event == ZMQ_EVENT_LISTENING);
242 event = get_monitor_event (server_mon, NULL, NULL);
243 assert (event == ZMQ_EVENT_ACCEPTED);
244 event = get_monitor_event (server_mon, NULL, NULL);
245 assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
246 event = get_monitor_event (server_mon, NULL, NULL);
247 assert (event == ZMQ_EVENT_CLOSED);
248 event = get_monitor_event (server_mon, NULL, NULL);
249 assert (event == ZMQ_EVENT_MONITOR_STOPPED);
250
251 // Close down the sockets
252 close_zero_linger (client_mon);
253 close_zero_linger (server_mon);
254 zmq_ctx_term (ctx);
255
256 return 0 ;
257 }
258
259
261 zmq(7)
262
264 This page was written by the 0MQ community. To make a change please
265 read the 0MQ Contribution Policy at
266 http://www.zeromq.org/docs:contributing.
267
268
269
2700MQ 4.3.4 01/21/2023 ZMQ_SOCKET_MONITOR(3)