zmq_socket_monitor.txt 7.44 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
zmq_ctx_socket_monitor(3)
=========================


NAME
----

zmq_socket_monitor - register a monitoring callback


SYNOPSIS
--------
*int zmq_socket_monitor (void '*socket', char * '*addr', int 'events');*


DESCRIPTION
-----------
The _zmq_socket_monitor()_ function shall spawn a 'PAIR' socket that publishes
socket state changes (events) over the inproc:// transport to a given endpoint.

21 22
Messages consist of 2 Frames, the first containing the event-id and the
associated value. The second frame holds the affected endpoint as string.
23

24 25 26
The layout of the first Frame is:
  16 bit event id
  32 bit event value
27

28 29
event id and value are in the native byte order (for the machine the
application is running on). There is no padding between the fields.
30

31 32
The event value has to be interpreted in the context of the event id.
See 'Supported events' below for details.
33 34 35 36 37 38

----

Only connection oriented (tcp and ipc) transports are supported in this initial
implementation.

39
----
40

41 42
Supported events
----------------
43 44 45 46 47

ZMQ_EVENT_CONNECTED: connection established
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_CONNECTED' event triggers when a connection has been established
to a remote peer. This can happen either synchronous or asynchronous.
Pieter Hintjens's avatar
Pieter Hintjens committed
48
Value is the FD of the newly connected socket.
49 50 51 52 53


ZMQ_EVENT_CONNECT_DELAYED: synchronous connect failed, it's being polled
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_CONNECT_DELAYED' event triggers when an immediate connection
Pieter Hintjens's avatar
Pieter Hintjens committed
54 55
attempt is delayed and its completion is being polled for.
Value has no meaning.
56 57 58 59 60 61 62


ZMQ_EVENT_CONNECT_RETRIED: asynchronous connect / reconnection attempt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_CONNECT_RETRIED' event triggers when a connection attempt
is being handled by reconnect timer. The reconnect interval's recomputed
for each attempt.
Pieter Hintjens's avatar
Pieter Hintjens committed
63
Value is the reconnect interval.
64 65 66 67 68 69


ZMQ_EVENT_LISTENING: socket bound to an address, ready to accept connections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_LISTENING' event triggers when a socket's successfully bound
to a an interface.
Pieter Hintjens's avatar
Pieter Hintjens committed
70
Value is the FD of the newly bound socket.
71 72 73 74 75 76


ZMQ_EVENT_BIND_FAILED: socket could not bind to an address
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_BIND_FAILED' event triggers when a socket could not bind to
a given interface.
Pieter Hintjens's avatar
Pieter Hintjens committed
77
Value is the errno generated by the bind call.
78 79 80 81 82 83


ZMQ_EVENT_ACCEPTED: connection accepted to bound interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_ACCEPTED' event triggers when a connection from a remote peer
has been established with a socket's listen address.
Pieter Hintjens's avatar
Pieter Hintjens committed
84
Value is the FD of the accepted socket.
85 86 87 88 89 90


ZMQ_EVENT_ACCEPT_FAILED: could not accept client connection
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_ACCEPT_FAILED' event triggers when a connection attempt to
a socket's bound address fails.
Pieter Hintjens's avatar
Pieter Hintjens committed
91
Value is the errno generated by accept.
92 93 94 95 96


ZMQ_EVENT_CLOSED: connection closed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_CLOSED' event triggers when a connection's underlying descriptor
97
has been closed.
Pieter Hintjens's avatar
Pieter Hintjens committed
98
Value is the former FD of the for the closed socket. FD has been closed already!
99 100 101 102 103


ZMQ_EVENT_CLOSE_FAILED: connection couldn't be closed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_CLOSE_FAILED' event triggers when a descriptor could not be
104
released back to the OS. Implementation note: ONLY FOR IPC SOCKETS.
Pieter Hintjens's avatar
Pieter Hintjens committed
105
Value is the errno generated by unlink.
106 107 108 109 110 111


ZMQ_EVENT_DISCONNECTED: broken session
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENT_DISCONNECTED' event triggers when the stream engine (tcp and ipc
specific) detects a corrupted / broken session.
Pieter Hintjens's avatar
Pieter Hintjens committed
112
Value is the FD of the socket.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137


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
-------
.Observing a 'REP' socket's connection state 
----
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
#include <stdio.h>
#include <zmq.h>
#include <pthread.h>
#include <string.h>
#include <assert.h>

static int read_msg(void* s, zmq_event_t* event, char* ep)
{
    int rc ;
    zmq_msg_t msg1;  // binary part
    zmq_msg_init (&msg1);
    zmq_msg_t msg2;  //  address part
    zmq_msg_init (&msg2);
    rc = zmq_msg_recv (&msg1, s, 0);
    if (rc == -1 && zmq_errno() == ETERM)
	return 1 ;
    assert (rc != -1);
    assert (zmq_msg_more(&msg1) != 0);
    rc = zmq_msg_recv (&msg2, s, 0);
    if (rc == -1 && zmq_errno() == ETERM)
	return 1;
    assert (rc != -1);
    assert (zmq_msg_more(&msg2) == 0);
    // copy binary data to event struct
    const char* data = (char*)zmq_msg_data(&msg1);
    memcpy(&(event->event), data, sizeof(event->event));
    memcpy(&(event->value), data+sizeof(event->event), sizeof(event->value));
    // copy address part
    const size_t len = zmq_msg_size(&msg2) ;
    ep = memcpy(ep, zmq_msg_data(&msg2), len);
    *(ep + len) = 0 ;
    return 0 ;
}

172 173 174 175
// REP socket monitor thread
static void *rep_socket_monitor (void *ctx)
{
    zmq_event_t event;
176
    static char addr[1025] ;
177 178
    int rc;

179 180
    printf("starting monitor...\n");

181 182 183 184 185
    void *s = zmq_socket (ctx, ZMQ_PAIR);
    assert (s);

    rc = zmq_connect (s, "inproc://monitor.rep");
    assert (rc == 0);
186
    while (!read_msg(s, &event, addr)) {
187 188
        switch (event.event) {
        case ZMQ_EVENT_LISTENING:
189 190
            printf ("listening socket descriptor %d\n", event.value);
            printf ("listening socket address %s\n", addr);
191 192
            break;
        case ZMQ_EVENT_ACCEPTED:
193 194
            printf ("accepted socket descriptor %d\n", event.value);
            printf ("accepted socket address %s\n", addr);
195 196
            break;
        case ZMQ_EVENT_CLOSE_FAILED:
197 198
            printf ("socket close failure error code %d\n", event.value);
            printf ("socket address %s\n", addr);
199 200
            break;
        case ZMQ_EVENT_CLOSED:
201 202
            printf ("closed socket descriptor %d\n", event.value);
            printf ("closed socket address %s\n", addr);
203 204
            break;
        case ZMQ_EVENT_DISCONNECTED:
205 206
            printf ("disconnected socket descriptor %d\n", event.value);
            printf ("disconnected socket address %s\n", addr);
207 208 209 210 211 212 213 214
            break;
        }
    }
    zmq_close (s);
    return NULL;
}


215 216 217 218 219 220 221 222 223 224 225 226
int main()
{
    const char* addr = "tcp://127.0.0.1:6666" ;
    pthread_t thread ;

    //  Create the infrastructure
    void *ctx = zmq_init (1);
    assert (ctx);

    // REP socket
    void* rep = zmq_socket (ctx, ZMQ_REP);
    assert (rep);
227

228 229 230 231 232
    // REP socket monitor, all events
    int rc = zmq_socket_monitor (rep, "inproc://monitor.rep", ZMQ_EVENT_ALL);
    assert (rc == 0);
    rc = pthread_create (&thread, NULL, rep_socket_monitor, ctx);
    assert (rc == 0);
233

234 235
    rc = zmq_bind (rep, addr);
    assert (rc == 0);
236

237 238
    // Allow some time for event detection
    zmq_sleep (1);
239

240 241 242
    // Close the REP socket
    rc = zmq_close (rep);
    assert (rc == 0);
243

244
    zmq_term (ctx);
245

246 247
    return 0 ;
}
248 249 250 251 252 253 254 255 256 257
----


SEE ALSO
--------
linkzmq:zmq[7]


AUTHORS
-------
258 259
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>.