libzmq/doc/zmq_socket_monitor_versioned.txt

312 lines
11 KiB
Plaintext
Raw Normal View History

zmq_socket_monitor_versioned(3)
=====================
NAME
----
zmq_socket_monitor_versioned - monitor socket events
SYNOPSIS
--------
*int zmq_socket_monitor_versioned (void '*socket', char '*endpoint', uint64_t 'events', int 'event_version');*
DESCRIPTION
-----------
The _zmq_socket_monitor_versioned()_ 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 for a version, use
the event value ZMQ_EVENT_ALL_V<version>, e.g. ZMQ_EVENT_ALL_V1. For non-DRAFT event
versions, this value will not change in the future, so new event types will only be
added in new versions (note that this is a change over zmq_socket_monitor and the
unversioned ZMQ_EVENT_ALL).
Note that event_version 2 is currently in DRAFT mode. The protocol may be
changed at any time for event_versions in DRAFT.
ZMQ_CURRENT_EVENT_VERSION and ZMQ_CURRENT_EVENT_VERSION_DRAFT are always defined
to the most recent stable or DRAFT event version, which are currently 1 resp. 2
This page describes the protocol for 'event_version' 2 only. For the protocol
used with 'event_version' 1, please refer to linkzmq:zmq_socket_monitor[3].
Each event is sent in multiple frames. The first frame contains an event
number (64 bits). The number and content of further frames depend on this
event number.
For all currently defined event types, the second frame contains an event
value (64 bits) that provides additional data according to the event number.
The third and fourth frames contain strings that specifies the affected
connection or endpoint. The third frame contains a string denoting the local
endpoint, while the fourth frame contains a string denoting the remote endpoint.
Either of these may be empty, depending on the event type and whether the
connection uses a bound or connected local endpoint.
Note that the format of the second and further frames, and also the number of
frames, may be different for events added in the future.
----
Monitoring events are only generated by some transports: At the moment these
are SOCKS, TCP, IPC, and TIPC. Note that it is not an error to call
'zmq_socket_monitor_versioned' on a socket that is connected or bound to some
other transport, as this may not be known at the time
'zmq_socket_monitor_versioned' is called. Also, a socket can be connected/bound
to multiple endpoints using different transports.
----
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 for 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 transport protocol of the monitor 'endpoint' is not supported. Monitor
sockets are required to use the inproc:// transport.
*EINVAL*::
The monitor 'endpoint' supplied does not exist.
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 <http://www.zeromq.org/docs:contributing>.