コード例 #1
0
ファイル: zre_msg.c プロジェクト: karinies/coast
zre_msg_t *
zre_msg_dup (zre_msg_t *self)
{
    if (!self)
        return NULL;
        
    zre_msg_t *copy = zre_msg_new (self->id);
    if (self->routing_id)
        copy->routing_id = zframe_dup (self->routing_id);
    switch (self->id) {
        case ZRE_MSG_HELLO:
            copy->sequence = self->sequence;
            copy->ipaddress = self->ipaddress? strdup (self->ipaddress): NULL;
            copy->mailbox = self->mailbox;
            copy->groups = self->groups? zlist_dup (self->groups): NULL;
            copy->status = self->status;
            copy->headers = self->headers? zhash_dup (self->headers): NULL;
            break;

        case ZRE_MSG_WHISPER:
            copy->sequence = self->sequence;
            copy->content = self->content? zmsg_dup (self->content): NULL;
            break;

        case ZRE_MSG_SHOUT:
            copy->sequence = self->sequence;
            copy->group = self->group? strdup (self->group): NULL;
            copy->content = self->content? zmsg_dup (self->content): NULL;
            break;

        case ZRE_MSG_JOIN:
            copy->sequence = self->sequence;
            copy->group = self->group? strdup (self->group): NULL;
            copy->status = self->status;
            break;

        case ZRE_MSG_LEAVE:
            copy->sequence = self->sequence;
            copy->group = self->group? strdup (self->group): NULL;
            copy->status = self->status;
            break;

        case ZRE_MSG_PING:
            copy->sequence = self->sequence;
            break;

        case ZRE_MSG_PING_OK:
            copy->sequence = self->sequence;
            break;

    }
    return copy;
}
コード例 #2
0
ファイル: zeb_broker.c プロジェクト: sappo/zebra
static void
write_message_to_xrap_handler (client_t *self)
{
    service_t *service = self->server->xrap;
    assert (service);
    ztrie_t *routes = NULL;

    zmsg_t *content = zmsg_dup (xrap_traffic_content (self->message));
    xrap_msg_t *msg = xrap_msg_decode (&content);
    char *route;
    int method = xrap_msg_id (msg);
    if (method == XRAP_MSG_GET) {
        route = (char *) xrap_msg_resource (msg);
        routes = service->get_routes;
    }
    else
    if (method == XRAP_MSG_POST) {
        route = (char *) xrap_msg_parent (msg);
        routes = service->post_routes;
    }
    else
    if (method == XRAP_MSG_PUT) {
        route = (char *) xrap_msg_resource (msg);
        routes = service->put_routes;
    }
    else
    if (method == XRAP_MSG_DELETE) {
        route = (char *) xrap_msg_resource (msg);
        routes = service->delete_routes;
    }
    else {
        xrap_traffic_set_status_code (self->message, XRAP_TRAFFIC_BAD_REQUEST);
        engine_set_exception (self, fail_event);
    }

    client_t *target;
    if (routes && ztrie_matches (routes, route)) {
        target = (client_t *) ztrie_hit_data (routes);
        //  Save message for broker
        target->msg = zmsg_dup (xrap_traffic_content (self->message));
        //  Trigger dispatch event
        target->callee = self;
        engine_send_event (target, xrap_message_event);
    }
    else {
        xrap_traffic_set_status_code (self->message, XRAP_TRAFFIC_NOT_FOUND);
        self->rc = -1;
    }

    //  Clean up
    xrap_msg_destroy (&msg);
}
コード例 #3
0
ファイル: mdcliapi.c プロジェクト: caucse-dev/zguide
zmsg_t *
mdcli_send (mdcli_t *self, char *service, zmsg_t *request)
{
    int retries_left = REQUEST_RETRIES;
    while (retries_left) {
        //  Prefix request with protocol frames
        //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
        //  Frame 2: Service name (printable string)
        zmsg_t *msg = zmsg_dup (request);
        zmsg_push (msg, service);
        zmsg_push (msg, MDPC_HEADER);
        zmsg_send (&msg, self->client);

        while (1) {
            //  Poll socket for a reply, with timeout
            zmq_pollitem_t items [] = { { self->client, 0, ZMQ_POLLIN, 0 } };
            zmq_poll (items, 1, REQUEST_TIMEOUT * 1000);

            //  If we got a reply, process it
            if (items [0].revents & ZMQ_POLLIN) {
                zmsg_t *msg = zmsg_recv (self->client);

                //  Don't try to handle errors, just assert noisily
                assert (zmsg_parts (msg) >= 3);

                char *header = zmsg_pop (msg);
                assert (strcmp (header, MDPC_HEADER) == 0);
                free (header);

                char *service = zmsg_pop (msg);
                assert (strcmp (service, service) == 0);
                free (service);

                return msg;     //  Success
            }
            else
            if (--retries_left) {
                //  Reconnect, and resend message
                s_connect_to_broker (self);
                zmsg_t *msg = zmsg_dup (request);
                zmsg_push (msg, service);
                zmsg_push (msg, MDPC_HEADER);
                zmsg_send (&msg, self->client);
            }
            else
                break;          //  Give up
        }
    }
    return NULL;
}
コード例 #4
0
ファイル: req.c プロジェクト: dinesh121991/flux-core
/* Return 'n' sequenced responses.
 */
static int nsrc_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    JSON o = Jnew ();
    int i, count;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "count", &count)) {
        if (flux_err_respond (h, EPROTO, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    for (i = 0; i < count; i++) {
        zmsg_t *cpy = zmsg_dup (*zmsg);
        if (!cpy)
            oom ();
        Jadd_int (o, "seq", i);
        if (flux_json_respond (h, o, &cpy) < 0)
            flux_log (h, LOG_ERR, "%s: flux_json_respond: %s", __FUNCTION__,
                      strerror (errno));
        zmsg_destroy (&cpy);
    }
    zmsg_destroy (zmsg);
done:
    Jput (o);
    return 0;
}
コード例 #5
0
int
main (int argc, char *argv[])
{

    if (argc != 3) {
        exit (-1);
    }

    int numb_msgs = atoi (argv[2]);

    zctx_t *ctx = zctx_new ();

    void *dealer = zsocket_new (ctx, ZMQ_DEALER);
    zsocket_set_linger (dealer, -1);
    zsocket_connect (dealer, "%s:9000", argv[1]);

    void *sub = zsocket_new (ctx, ZMQ_SUB);
    zsocket_connect (sub, "%s:9002", argv[1]);
    zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "all", 4);

    int64_t time[2];

    zmq_pollitem_t pollitem[1] = { {sub, 0, ZMQ_POLLIN}
    };

    zmq_poll (pollitem, 1, -1);
    zmsg_t *signal = zmsg_recv (sub);
    zmsg_destroy (&signal);

    char blob[SIZE] = { 0 };
    zmsg_t *msg = zmsg_new ();
    zframe_t *frame = zframe_new (blob, SIZE);
    zmsg_add (msg, frame);

    time[0] = zclock_time ();

    int i;
    for (i = 0; i < numb_msgs; i++) {
        zmsg_t *nmsg = zmsg_dup (msg);
        zmsg_send (&nmsg, dealer);


    }
    time[1] = zclock_time ();

    zmsg_destroy (&msg);

    zmq_poll (pollitem, 1, -1);
    msg = zmsg_recv (sub);
    zmsg_destroy (&msg);


    msg = zmsg_new ();
    frame = zframe_new (time, sizeof (int64_t) * 2);
    zmsg_add (msg, frame);
    zmsg_send (&msg, dealer);


    zctx_destroy (&ctx);
}
コード例 #6
0
ファイル: flcliapi.c プロジェクト: tzuryby/zguide
static void *
flcliapi_task (void *context) 
{
    agent_t *self = agent_new (context, "inproc://flcliapi");
    zmq_pollitem_t items [] = { 
        { self->control, 0, ZMQ_POLLIN, 0 },
        { self->router, 0, ZMQ_POLLIN, 0 } 
    };

    while (!s_interrupted) {
        //  Calculate tickless timer, up to 1 hour
        uint64_t tickless = s_clock () + 1000 * 3600;
        if (self->request
        &&  tickless > self->expires)
            tickless = self->expires;
        zhash_apply (self->servers, server_tickless, &tickless);

        int rc = zmq_poll (items, 2, (tickless - s_clock ()) * 1000);
        if (rc == -1 && errno == ETERM)
            break;              //  Context has been shut down

        if (items [0].revents & ZMQ_POLLIN)
            agent_control_message (self);

        if (items [1].revents & ZMQ_POLLIN)
            agent_router_message (self);

        //  If we're processing a request, dispatch to next server
        if (self->request) {
            if (s_clock () >= self->expires) {
                //  Request expired, kill it
                zmsg_t *reply = zmsg_new ("FAILED");
                zmsg_send (&reply, self->control);
                zmsg_destroy (&self->request);
            }
            else {
                //  Find server to talk to, remove any expired ones
                while (zlist_size (self->actives)) {
                    server_t *server = (server_t *) zlist_first (self->actives);
                    if (s_clock () >= server->expires) {
                        zlist_pop (self->actives);
                        server->alive = 0;
                    }
                    else {
                        zmsg_t *request = zmsg_dup (self->request);
                        zmsg_push (request, server->endpoint);
                        zmsg_send (&request, self->router);
                        break;
                    }
                }
            }
        }
        //  Disconnect and delete any expired servers
        //  Send heartbeats to idle servers if needed
        zhash_apply (self->servers, server_ping, self->router);
    }
    agent_destroy (&self);
    return NULL;
}
コード例 #7
0
ファイル: mdwrkapi.c プロジェクト: caucse-dev/zguide
zmsg_t *
mdwrk_recv (mdwrk_t *self, zmsg_t *reply)
{
    //  Format and send the reply if we were provided one
    assert (reply || !self->expect_reply);
    if (reply) {
        zmsg_t *msg = zmsg_dup (reply);
        zmsg_push (msg, MDPS_REPLY);
        zmsg_push (msg, MDPS_HEADER);
        zmsg_send (&msg, self->worker);
    }
    self->expect_reply = 1;

    while (1) {
        zmq_pollitem_t items [] = { { self->worker,  0, ZMQ_POLLIN, 0 } };
        zmq_poll (items, 1, HEARTBEAT_INTERVAL * 1000);

        if (items [0].revents & ZMQ_POLLIN) {
            zmsg_t *msg = zmsg_recv (self->worker);
            self->liveness = HEARTBEAT_LIVENESS;

            //  Don't try to handle errors, just assert noisily
            assert (zmsg_parts (msg) >= 3);

            char *header = zmsg_pop (msg);
            assert (strcmp (header, MDPS_HEADER) == 0);
            free (header);

            char *command = zmsg_pop (msg);
            if (strcmp (command, MDPS_REQUEST) == 0)
                return msg;     //  We have a request to process
            else
            if (strcmp (command, MDPS_HEARTBEAT) == 0)
                ;               //  Do nothing for heartbeats
            else
            if (strcmp (command, MDPS_DISCONNECT) == 0)
                break;          //  Return empty handed
            else {
                printf ("E: invalid input message (%d)\n", (int) command [1]);
                zmsg_dump (msg);
            }
            free (command);
        }
        else
        if (--self->liveness == 0) {
            s_sleep (RECONNECT_INTERVAL);
            s_connect_to_broker (self);
        }
        //  Send HEARTBEAT if it's time
        if (s_clock () > self->heartbeat_at) {
            self->heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
            s_send (self->worker, "HEARTBEAT");
        }
    }
    //  We exit if we've been disconnected
    return NULL;
}
コード例 #8
0
void _rrwrk_send(void *socket, char *command, zmsg_t *msg)
{
    msg = msg ? zmsg_dup(msg):zmsg_new();

    zmsg_pushstr(msg, command);
    zmsg_pushstr(msg, RR_WORKER);
    zmsg_pushstr(msg, "");

    zmsg_send(&msg, socket);
}
コード例 #9
0
ファイル: xbarrier.c プロジェクト: trws/flux-barrier
static int send_enter_response (const char *key, void *item, void *arg)
{
    zmsg_t *zmsg = item;
    barrier_t *b = arg;
    zmsg_t *cpy;

    if (!(cpy = zmsg_dup (zmsg)))
        oom ();
    flux_respond_errnum (b->ctx->h, &cpy, b->errnum);
    return 0;
}
コード例 #10
0
ファイル: zre_msg.c プロジェクト: karinies/coast
int
zre_msg_send_whisper (
    void *output,
    uint16_t sequence,
    zmsg_t *content)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_WHISPER);
    zre_msg_set_sequence (self, sequence);
    zmsg_t *content_copy = zmsg_dup (content);
    zre_msg_set_content (self, &content_copy);
    return zre_msg_send (&self, output);
}
コード例 #11
0
ファイル: zeb_broker.c プロジェクト: sappo/zebra
static void
write_message_to_xrap_client (client_t *self)
{
    zuuid_t *client_id = xrap_traffic_sender (self->message);
    assert (client_id);
    client_t *client = (client_t *) zhashx_lookup (self->server->clients, zuuid_str (client_id));
    if (client) {
        //  Save message for broker
        client->msg = zmsg_dup (xrap_traffic_content (self->message));
        client->callee = NULL;
        engine_send_event (client, xrap_message_event);
    }
}
コード例 #12
0
ファイル: zre_msg.c プロジェクト: karinies/coast
int
zre_msg_send_shout (
    void *output,
    uint16_t sequence,
    const char *group,
    zmsg_t *content)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_SHOUT);
    zre_msg_set_sequence (self, sequence);
    zre_msg_set_group (self, group);
    zmsg_t *content_copy = zmsg_dup (content);
    zre_msg_set_content (self, &content_copy);
    return zre_msg_send (&self, output);
}
コード例 #13
0
ファイル: messages.c プロジェクト: GoogleLonely/satan
zmsg_t *messages_parse_result2msg(char *device_id, int code, char *msgid, zmsg_t *original)
{
  zmsg_t *answer = NULL;

  switch (code) {
    case MSG_ANSWER_UNREADABLE:
      {
        answer = zmsg_dup(original);
        zmsg_pushstr(answer, "%s", MSG_ANSWER_STR_UNREADABLE);
        zmsg_pushstr(answer, "%s", "");
        zmsg_pushstr(answer, "%s", device_id);
      } break;
    case MSG_ANSWER_PARSEERROR:
      {
        answer = zmsg_dup(original);
        zmsg_pushstr(answer, "%s", MSG_ANSWER_STR_PARSEERROR);
        zmsg_pushstr(answer, "%s", msgid);
        zmsg_pushstr(answer, "%s", device_id);
      } break;
    case MSG_ANSWER_BADCRC:
      {
        answer = zmsg_dup(original);
        zmsg_pushstr(answer, "%s", MSG_ANSWER_STR_BADCRC);
        zmsg_pushstr(answer, "%s", msgid);
        zmsg_pushstr(answer, "%s", device_id);
      } break;
    case MSG_ANSWER_ACCEPTED:
      {
        answer = zmsg_new();
        zmsg_pushstr(answer, "%s", MSG_ANSWER_STR_ACCEPTED);
        zmsg_pushstr(answer, "%s", msgid);
        zmsg_pushstr(answer, "%s", device_id);
      } break;
  }

  return answer;
}
コード例 #14
0
static
void subscriber_publish_duplicate(zmsg_t *msg, void *socket)
{
    static size_t seq = 0;
    zmsg_t *msg_copy = zmsg_dup(msg);
    zmsg_addstrf(msg_copy, "%zu", ++seq);
    zframe_t *frame = zmsg_pop(msg_copy);
    while (frame != NULL) {
        zframe_t *next_frame = zmsg_pop(msg_copy);
        int more = next_frame ? ZFRAME_MORE : 0;
        if (zframe_send(&frame, socket, ZFRAME_DONTWAIT|more) == -1)
            break;
        frame = next_frame;
    }
    zmsg_destroy(&msg_copy);
}
コード例 #15
0
ファイル: broker.c プロジェクト: tnako/DP
static void s_worker_send(worker_t *self, char *command, zmsg_t *msg)
{
    msg = (msg ? zmsg_dup(msg): zmsg_new());
	
    zmsg_pushstr(msg, command);
    zmsg_pushstr(msg, MDPW_WORKER);

    //  Stack routing envelope to start of message
    zmsg_wrap(msg, zframe_dup(self->identity));

    if (self->broker->verbose) {
        zclock_log ("I: sending %s to worker", mdps_commands [(int) *command]);
        zmsg_dump(msg);
    }
    zmsg_send(&msg, self->broker->socket);
}
コード例 #16
0
ファイル: mdbroker.c プロジェクト: rryqszq4/sweet-clib
static void
s_worker_send(worker_t *self, char *command, char *option, zmsg_t *msg)
{
	msg = msg ? zmsg_dup(msg) : zmsg_new();

	if (option)
		zmsg_pushstr(msg, option);
	zmsg_pushstr(msg, command);
	zmsg_pushstr(msg, MDPW_WORKER);

	zmsg_wrap(msg, zframe_dup(self->identity));

	if (self->broker->verbose){
		zclock_log("I: sending %s to worker", mdps_commands[(int) *command]);
		zmsg_dump(msg);
	}
	zmsg_send(&msg, self->broker->socket);

}
コード例 #17
0
ファイル: flclient1.c プロジェクト: Alexis-D/zguide
static zmsg_t *
s_try_request (zctx_t *ctx, char *endpoint, zmsg_t *request)
{
    printf ("I: trying echo service at %s...\n", endpoint);
    void *client = zsocket_new (ctx, ZMQ_REQ);
    zsocket_connect (client, endpoint);

    //  Send request, wait safely for reply
    zmsg_t *msg = zmsg_dup (request);
    zmsg_send (&msg, client);
    zmq_pollitem_t items [] = { { client, 0, ZMQ_POLLIN, 0 } };
    zmq_poll (items, 1, REQUEST_TIMEOUT * ZMQ_POLL_MSEC);
    zmsg_t *reply = NULL;
    if (items [0].revents & ZMQ_POLLIN)
        reply = zmsg_recv (client);

    //  Close socket in any case, we're done with it now
    zsocket_destroy (ctx, client);
    return reply;
}
コード例 #18
0
ファイル: mdp_worker.c プロジェクト: methodmissing/majordomo
static void
s_mdp_worker_send_to_broker (mdp_worker_t *self, char *command, char *option,
                        zmsg_t *msg)
{
    msg = msg? zmsg_dup (msg): zmsg_new ();

    //  Stack protocol envelope to start of message
    if (option)
        zmsg_pushstr (msg, option);
    zmsg_pushstr (msg, command);
    zmsg_pushstr (msg, MDPW_WORKER);
    zmsg_pushstr (msg, "");

    if (self->verbose) {
        zclock_log ("I: sending %s to broker",
            mdpw_commands [(int) *command]);
        zmsg_dump (msg);
    }
    zmsg_send (&msg, self->worker);
}
コード例 #19
0
ファイル: zproxy.c プロジェクト: maxkozlovsky/czmq
static void
s_send_proxy_command (zactor_t *proxy, const char *command, int selected_sockets, const char *string, ...)
{
    zmsg_t *msg = zmsg_new ();
    if (!msg)
        assert (false);
    va_list args;
    va_start (args, string);
    while (string) {
        zmsg_addstr (msg, string);
        string = va_arg (args, char *);
    }
    va_end (args);
    for (int index = 0; index < SOCKETS; index++) {
        if (selected_sockets & (1 << index)) {
            s_send_proxy_msg (proxy, command, (proxy_socket)index, zmsg_dup (msg));
            zsock_wait (proxy);
        }
    }
    zmsg_destroy (&msg);
}
コード例 #20
0
ファイル: mdbroker.c プロジェクト: Neopallium/zguide
static void
s_worker_send (
    broker_t *self, worker_t *worker,
    char *command, char *option, zmsg_t *msg)
{
    msg = msg? zmsg_dup (msg): zmsg_new (NULL);

    //  Stack protocol envelope to start of message
    if (option)                 //  Optional frame after command
        zmsg_push (msg, option);
    zmsg_push (msg, command);
    zmsg_push (msg, MDPW_WORKER);
    //  Stack routing envelope to start of message
    zmsg_wrap (msg, worker->identity, "");

    if (self->verbose) {
        s_console ("I: sending %s to worker",
            mdps_commands [(int) *command]);
        zmsg_dump (msg);
    }
    zmsg_send (&msg, self->socket);
}
コード例 #21
0
ファイル: mdbroker.c プロジェクト: Alex-Benveniste/zguide
static void
s_worker_send (broker_t *self, worker_t *worker, char *command,
               char *option, zmsg_t *msg)
{
    msg = msg? zmsg_dup (msg): zmsg_new ();

    //  Stack protocol envelope to start of message
    if (option)
        zmsg_pushstr (msg, option);
    zmsg_pushstr (msg, command);
    zmsg_pushstr (msg, MDPW_WORKER);

    //  Stack routing envelope to start of message
    zmsg_wrap (msg, zframe_dup (worker->address));

    if (self->verbose) {
        zclock_log ("I: sending %s to worker",
            mdps_commands [(int) *command]);
        zmsg_dump (msg);
    }
    zmsg_send (&msg, self->socket);
}
コード例 #22
0
ファイル: client_proxy.c プロジェクト: zgwmike/TWPS
static int reader_rep_event(zloop_t *loop, zsock_t *sink, void *arg) {
    client_proxy_t *self = arg;
    zmsg_t *request = zmsg_recv(self->rep);
    char *correlation_id = zmsg_popstr(request);
    zmsg_t *dup = zmsg_dup(request);
    if (!request) {
        return 0;
    }
    char *command = zmsg_popstr(request);
    bool is_ticket_command =
            streq(command, "PRINT") || streq(command, "GETTICKETINFO") || streq(command, "DETAILREPORT") ||
            streq(command, "REPORT") || streq(command, "SIMPLEREPORT") || streq(command, "SUMMARY") || streq(command,"UNPRINT");
    if (self->ticket_store_req != NULL && is_ticket_command) {
        zmsg_send(&dup, self->ticket_store_req);
        zmsg_t *resp = zmsg_recv(self->ticket_store_req);
        zmsg_pushstr(resp, correlation_id);
        if (self->verbose) {
            zsys_debug("client proxy: sending response from ticket store for command %s", command);
            zmsg_print(resp);
        }
        zmsg_send(&resp, self->rep);
    }
    bool is_printer_store_command = streq(command, "GETPRINTERS") || streq(command, "GETPRINTER") || streq(command, "SCANPRINTERS");
    if (self->printer_store_req != NULL && is_printer_store_command) {
        zmsg_send(&dup, self->printer_store_req);
        zmsg_t *resp = zmsg_recv(self->printer_store_req);
        zmsg_pushstr(resp, correlation_id);
        if (self->verbose) {
            zsys_debug("client proxy: sending response from printer store");
            zmsg_print(resp);
        }
        zmsg_send(&resp, self->rep);
    }
    zstr_free(&correlation_id);
    zstr_free(&command);
    zmsg_destroy(&request);
    return 0;
}
コード例 #23
0
ファイル: flclient2.c プロジェクト: Neopallium/zguide
zmsg_t *
flclient_request (flclient_t *self, zmsg_t **request_p)
{
    assert (self);
    assert (*request_p);
    zmsg_t *request = *request_p;
    
    //  Prefix request with sequence number and empty envelope
    char sequence_text [10];
    sprintf (sequence_text, "%u", ++self->sequence);
    zmsg_push (request, sequence_text);
    zmsg_push (request, "");
    
    //  Blast the request to all connected servers
    int server;
    for (server = 0; server < self->servers; server++) {
        zmsg_t *msg = zmsg_dup (request);
        zmsg_send (&msg, self->socket);
    }
    //  Wait for a matching reply to arrive from anywhere
    //  Since we can poll several times, calculate each one
    zmsg_t *reply = NULL;
    uint64_t endtime = s_clock () + GLOBAL_TIMEOUT;
    while (s_clock () < endtime) {
        zmq_pollitem_t items [] = { { self->socket, 0, ZMQ_POLLIN, 0 } };
        zmq_poll (items, 1, (endtime - s_clock ()) * 1000);
        if (items [0].revents & ZMQ_POLLIN) {
            reply = zmsg_recv (self->socket);
            assert (zmsg_parts (reply) == 3);
            free (zmsg_pop (reply));
            if (atoi (zmsg_address (reply)) == self->sequence)
                break;
            zmsg_destroy (&reply);
        }
    }
    zmsg_destroy (request_p);
    return reply;
}
コード例 #24
0
ファイル: asyncsrv.c プロジェクト: darksuji/zguide
//  Accept a request and reply with the same text a random number of
//  times, with random delays between replies.
//
static void *
server_worker (void *context) {
    void *worker = zmq_socket (context, ZMQ_XREQ);
    zmq_connect (worker, "inproc://backend");

    while (1) {
        //  The XREQ socket gives us the address envelope and message
        zmsg_t *msg = zmsg_recv (worker);
        assert (zmsg_parts (msg) == 2);
        
        //  Send 0..4 replies back
        int reply, replies = randof (5);
        for (reply = 0; reply < replies; reply++) {
            //  Sleep for some fraction of a second
            struct timespec t = { 0, randof (100000000) + 1 };
            nanosleep (&t, NULL);
            zmsg_t *dup = zmsg_dup (msg);
            zmsg_send (&dup, worker);
        }
        zmsg_destroy (&msg);
    }
    zmq_close (worker);
    return (NULL);
}
コード例 #25
0
ファイル: zyre_node.c プロジェクト: codebrainz/zyre
static int
zyre_node_recv_peer (zyre_node_t *self)
{
    //  Router socket tells us the identity of this peer
    zre_msg_t *msg = zre_msg_recv (self->inbox);
    if (msg == NULL)
        return 0;               //  Interrupted

    //  First frame is sender identity, holding binary UUID
    zuuid_t *uuid = zuuid_new ();
    zuuid_set (uuid, zframe_data (zre_msg_address (msg)));

    //  On HELLO we may create the peer if it's unknown
    //  On other commands the peer must already exist
    zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid));
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        peer = zyre_node_require_peer (self, uuid, zre_msg_ipaddress (msg), zre_msg_mailbox (msg));
        assert (peer);
        zyre_peer_set_ready (peer, true);
    }
    //  Ignore command if peer isn't ready
    if (peer == NULL || !zyre_peer_ready (peer)) {
        zre_msg_destroy (&msg);
        zuuid_destroy (&uuid);
        return 0;
    }
    if (!zyre_peer_check_message (peer, msg)) {
        zclock_log ("W: [%s] lost messages from %s", zuuid_str (self->uuid), zuuid_str (uuid));
        assert (false);
    }

    //  Now process each command
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        //  Tell the caller about the peer
        zstr_sendm (self->pipe, "ENTER");
        zstr_sendm (self->pipe, zuuid_str (uuid));
        zframe_t *headers = zhash_pack (zre_msg_headers (msg));
        zframe_send (&headers, self->pipe, 0);
        
        //  Join peer to listed groups
        char *name = zre_msg_groups_first (msg);
        while (name) {
            zyre_node_join_peer_group (self, peer, name);
            name = zre_msg_groups_next (msg);
        }
        //  Hello command holds latest status of peer
        zyre_peer_set_status (peer, zre_msg_status (msg));
        
        //  Store peer headers for future reference
        zyre_peer_set_headers (peer, zre_msg_headers (msg));

        //  If peer is a ZRE/LOG collector, connect to it
        char *collector = zre_msg_headers_string (msg, "X-ZRELOG", NULL);
        if (collector)
            zyre_log_connect (self->log, collector);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_WHISPER) {
        //  Pass up to caller API as WHISPER event
        zstr_sendm (self->pipe, "WHISPER");
        zstr_sendm (self->pipe, zuuid_str (uuid));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->pipe);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_SHOUT) {
        //  Pass up to caller as SHOUT event
        zstr_sendm (self->pipe, "SHOUT");
        zstr_sendm (self->pipe, zuuid_str (uuid));
        zstr_sendm (self->pipe, zre_msg_group (msg));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->pipe);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_PING) {
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK);
        zyre_peer_send (peer, &msg);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_JOIN) {
        zyre_node_join_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_LEAVE) {
        zyre_node_leave_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    zuuid_destroy (&uuid);
    zre_msg_destroy (&msg);
    
    //  Activity from peer resets peer timers
    zyre_peer_refresh (peer);
    return 0;
}
コード例 #26
0
ファイル: mdcliapi.c プロジェクト: Neopallium/zguide
zmsg_t *
mdcli_send (mdcli_t *self, char *service, zmsg_t **request_p)
{
    assert (self);
    assert (request_p);
    zmsg_t *request = *request_p;

    //  Prefix request with protocol frames
    //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
    //  Frame 2: Service name (printable string)
    zmsg_push (request, service);
    zmsg_push (request, MDPC_CLIENT);
    if (self->verbose) {
        s_console ("I: send request to '%s' service:", service);
        zmsg_dump (request);
    }

    int retries_left = self->retries;
    while (retries_left && !s_interrupted) {
        zmsg_t *msg = zmsg_dup (request);
        zmsg_send (&msg, self->client);

        while (!s_interrupted) {
            //  Poll socket for a reply, with timeout
            zmq_pollitem_t items [] = { 
                { self->client, 0, ZMQ_POLLIN, 0 } };
            zmq_poll (items, 1, self->timeout * 1000);

            //  If we got a reply, process it
            if (items [0].revents & ZMQ_POLLIN) {
                zmsg_t *msg = zmsg_recv (self->client);
                if (self->verbose) {
                    s_console ("I: received reply:");
                    zmsg_dump (msg);
                }
                //  Don't try to handle errors, just assert noisily
                assert (zmsg_parts (msg) >= 3);

                char *header = zmsg_pop (msg);
                assert (streq (header, MDPC_CLIENT));
                free (header);

                char *reply_service = zmsg_pop (msg);
                assert (streq (reply_service, service));
                free (reply_service);

                zmsg_destroy (&request);
                return msg;     //  Success
            }
            else
            if (--retries_left) {
                if (self->verbose)
                    s_console ("W: no reply, reconnecting...");
                //  Reconnect, and resend message
                s_mdcli_connect_to_broker (self);
                zmsg_t *msg = zmsg_dup (request);
                zmsg_send (&msg, self->client);
            }
            else {
                if (self->verbose)
                    s_console ("W: permanent error, abandoning request");
                break;          //  Give up
            }
        }
    }
    if (s_interrupted)
        printf ("W: interrupt received, killing client...\n");
    zmsg_destroy (&request);
    return NULL;
}
コード例 #27
0
ファイル: zeb_broker.c プロジェクト: sappo/zebra
void
zeb_broker_test (bool verbose)
{
    printf (" * zeb_broker: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    zactor_t *server = zactor_new (zeb_broker, "broker");
    if (verbose)
        zstr_send (server, "VERBOSE");

    zstr_sendx (server, "BIND", "tcp://127.0.0.1:9999", NULL);

    zsock_t* client = zsock_new_dealer (">tcp://127.0.0.1:9999");
    zsock_t* worker = zsock_new_dealer (">tcp://127.0.0.1:9999");
    assert (client);
    assert (worker);

    xrap_traffic_t *traffic = xrap_traffic_new ();

    //  Invalid Command
    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_XRAP_OFFER);
    xrap_traffic_send (traffic, client);
    xrap_traffic_recv (traffic, client);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_ERROR);
    assert (xrap_traffic_status_code (traffic) == XRAP_TRAFFIC_COMMAND_INVALID);

    //  Open Connections for client & worker
    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_CONNECTION_OPEN);
    xrap_traffic_send (traffic, client);
    xrap_traffic_recv (traffic, client);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_OK);

    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_CONNECTION_OPEN);
    xrap_traffic_send (traffic, worker);
    xrap_traffic_recv (traffic, worker);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_OK);

    //  Provide Rubish Offering
    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_XRAP_OFFER);
    xrap_traffic_set_route (traffic, "///");
    xrap_traffic_set_method (traffic, "GET");
    xrap_traffic_send (traffic, worker);
    xrap_traffic_recv (traffic, worker);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_FAIL);
    assert (xrap_traffic_status_code (traffic) == XRAP_TRAFFIC_CONFLICT);

    //  Provide Offering
    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_XRAP_OFFER);
    xrap_traffic_set_route (traffic, "/foo/{[^/]}");
    xrap_traffic_set_method (traffic, "GET");
    xrap_traffic_send (traffic, worker);
    xrap_traffic_recv (traffic, worker);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_OK);

    //  Send Request
    xrap_msg_t *xmsg = xrap_msg_new (XRAP_MSG_GET);
    xrap_msg_set_resource (xmsg, "%s", "/foo/bar");
    zmsg_t *msg = xrap_msg_encode (&xmsg);
    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_XRAP_SEND);
    xrap_traffic_set_content (traffic, &msg);
    xrap_traffic_send (traffic, client);
    xrap_traffic_recv (traffic, client);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_OK);

    //  Receive Request
    xrap_traffic_recv (traffic, worker);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_XRAP_DELIVER);
    msg = zmsg_dup (xrap_traffic_content (traffic));
    xmsg = xrap_msg_decode (&msg);
    assert (xrap_msg_id (xmsg) == XRAP_MSG_GET);
    assert (streq ("/foo/bar", xrap_msg_resource (xmsg)));
    xrap_msg_destroy (&xmsg);

    //  Send Response
    xmsg = xrap_msg_new (XRAP_MSG_GET_OK);
    xrap_msg_set_status_code (xmsg, 200);
    xrap_msg_set_content_type (xmsg, "text/hello");
    xrap_msg_set_content_body (xmsg, "Hello World!");
    msg = xrap_msg_encode (&xmsg);
    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_XRAP_DELIVER);
    xrap_traffic_set_content (traffic, &msg);
    xrap_traffic_send (traffic, worker);

    //  Receive Response
    xrap_traffic_recv (traffic, client);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_XRAP_DELIVER);
    msg = zmsg_dup (xrap_traffic_content (traffic));
    xmsg = xrap_msg_decode (&msg);
    assert (xrap_msg_id (xmsg) == XRAP_MSG_GET_OK);
    assert (xrap_msg_status_code (xmsg) == 200);
    assert (streq ("text/hello", xrap_msg_content_type (xmsg)));
    assert (streq ("Hello World!", xrap_msg_content_body (xmsg)));
    xrap_msg_destroy (&xmsg);

    //  Send Request 2
    xmsg = xrap_msg_new (XRAP_MSG_GET);
    xrap_msg_set_resource (xmsg, "%s", "/fou/baz");
    msg = xrap_msg_encode (&xmsg);
    xrap_traffic_set_id (traffic, XRAP_TRAFFIC_XRAP_SEND);
    xrap_traffic_set_content (traffic, &msg);
    xrap_traffic_send (traffic, client);
    xrap_traffic_recv (traffic, client);
    assert (xrap_traffic_id (traffic) == XRAP_TRAFFIC_FAIL);
    assert (xrap_traffic_status_code (traffic) == XRAP_TRAFFIC_NOT_FOUND);

    xrap_traffic_destroy (&traffic);

    //  Finished, we can clean up
    zsock_destroy (&client);
    zsock_destroy (&worker);
    zactor_destroy (&server);
    //  @end
    printf ("OK\n");
}
コード例 #28
0
ファイル: QmlZmsg.cpp プロジェクト: dadavita/stalk
///
//  Create copy of message, as new message object. Returns a fresh zmsg_t
//  object. If message is null, or memory was exhausted, returns null.   
QmlZmsg *QmlZmsg::dup () {
    QmlZmsg *retQ_ = new QmlZmsg ();
    retQ_->self = zmsg_dup (self);
    return retQ_;
};
コード例 #29
0
ファイル: zmsg.c プロジェクト: dadavita/stalk
void
zmsg_test (bool verbose)
{
    printf (" * zmsg: ");

    int rc = 0;
    //  @selftest
    //  Create two PAIR sockets and connect over inproc
    zsock_t *output = zsock_new_pair ("@inproc://zmsg.test");
    assert (output);
    zsock_t *input = zsock_new_pair (">inproc://zmsg.test");
    assert (input);

    //  Test send and receive of single-frame message
    zmsg_t *msg = zmsg_new ();
    assert (msg);
    zframe_t *frame = zframe_new ("Hello", 5);
    assert (frame);
    zmsg_prepend (msg, &frame);
    assert (zmsg_size (msg) == 1);
    assert (zmsg_content_size (msg) == 5);
    rc = zmsg_send (&msg, output);
    assert (msg == NULL);
    assert (rc == 0);

    msg = zmsg_recv (input);
    assert (msg);
    assert (zmsg_size (msg) == 1);
    assert (zmsg_content_size (msg) == 5);
    zmsg_destroy (&msg);

    //  Test send and receive of multi-frame message
    msg = zmsg_new ();
    assert (msg);
    rc = zmsg_addmem (msg, "Frame0", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame1", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame2", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame3", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame4", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame5", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame6", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame7", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame8", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame9", 6);
    assert (rc == 0);
    zmsg_t *copy = zmsg_dup (msg);
    assert (copy);
    rc = zmsg_send (&copy, output);
    assert (rc == 0);
    rc = zmsg_send (&msg, output);
    assert (rc == 0);

    copy = zmsg_recv (input);
    assert (copy);
    assert (zmsg_size (copy) == 10);
    assert (zmsg_content_size (copy) == 60);
    zmsg_destroy (&copy);

    msg = zmsg_recv (input);
    assert (msg);
    assert (zmsg_size (msg) == 10);
    assert (zmsg_content_size (msg) == 60);

    // create empty file for null test
    FILE *file = fopen ("zmsg.test", "w");
    assert (file);
    fclose (file);

    file = fopen ("zmsg.test", "r");
    zmsg_t *null_msg = zmsg_load (NULL, file);
    assert (null_msg == NULL);
    fclose (file);
    remove ("zmsg.test");

    //  Save to a file, read back
    file = fopen ("zmsg.test", "w");
    assert (file);
    rc = zmsg_save (msg, file);
    assert (rc == 0);
    fclose (file);

    file = fopen ("zmsg.test", "r");
    rc = zmsg_save (msg, file);
    assert (rc == -1);
    fclose (file);
    zmsg_destroy (&msg);

    file = fopen ("zmsg.test", "r");
    msg = zmsg_load (NULL, file);
    assert (msg);
    fclose (file);
    remove ("zmsg.test");
    assert (zmsg_size (msg) == 10);
    assert (zmsg_content_size (msg) == 60);

    //  Remove all frames except first and last
    int frame_nbr;
    for (frame_nbr = 0; frame_nbr < 8; frame_nbr++) {
        zmsg_first (msg);
        frame = zmsg_next (msg);
        zmsg_remove (msg, frame);
        zframe_destroy (&frame);
    }
    //  Test message frame manipulation
    assert (zmsg_size (msg) == 2);
    frame = zmsg_last (msg);
    assert (zframe_streq (frame, "Frame9"));
    assert (zmsg_content_size (msg) == 12);
    frame = zframe_new ("Address", 7);
    assert (frame);
    zmsg_prepend (msg, &frame);
    assert (zmsg_size (msg) == 3);
    rc = zmsg_addstr (msg, "Body");
    assert (rc == 0);
    assert (zmsg_size (msg) == 4);
    frame = zmsg_pop (msg);
    zframe_destroy (&frame);
    assert (zmsg_size (msg) == 3);
    char *body = zmsg_popstr (msg);
    assert (streq (body, "Frame0"));
    free (body);
    zmsg_destroy (&msg);

    //  Test encoding/decoding
    msg = zmsg_new ();
    assert (msg);
    byte *blank = (byte *) zmalloc (100000);
    assert (blank);
    rc = zmsg_addmem (msg, blank, 0);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 1);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 253);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 254);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 255);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 256);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 65535);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 65536);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 65537);
    assert (rc == 0);
    free (blank);
    assert (zmsg_size (msg) == 9);
    byte *buffer;
    size_t buffer_size = zmsg_encode (msg, &buffer);
    zmsg_destroy (&msg);
    msg = zmsg_decode (buffer, buffer_size);
    assert (msg);
    free (buffer);
    zmsg_destroy (&msg);

    //  Test submessages
    msg = zmsg_new ();
    assert (msg);
    zmsg_t *submsg = zmsg_new ();
    zmsg_pushstr (msg, "matr");
    zmsg_pushstr (submsg, "joska");
    rc = zmsg_addmsg (msg, &submsg);
    assert (rc == 0);
    assert (submsg == NULL);
    submsg = zmsg_popmsg (msg);
    assert (submsg == NULL);   // string "matr" is not encoded zmsg_t, so was discarded
    submsg = zmsg_popmsg (msg);
    assert (submsg);
    body = zmsg_popstr (submsg);
    assert (streq (body, "joska"));
    free (body);
    zmsg_destroy (&submsg);
    frame = zmsg_pop (msg);
    assert (frame == NULL);
    zmsg_destroy (&msg);

    //  Test comparison of two messages
    msg = zmsg_new ();
    zmsg_addstr (msg, "One");
    zmsg_addstr (msg, "Two");
    zmsg_addstr (msg, "Three");
    zmsg_t *msg_other = zmsg_new ();
    zmsg_addstr (msg_other, "One");
    zmsg_addstr (msg_other, "Two");
    zmsg_addstr (msg_other, "One-Hundred");
    zmsg_t *msg_dup = zmsg_dup (msg);
    zmsg_t *empty_msg = zmsg_new ();
    zmsg_t *empty_msg_2 = zmsg_new ();
    assert (zmsg_eq (msg, msg_dup));
    assert (!zmsg_eq (msg, msg_other));
    assert (zmsg_eq (empty_msg, empty_msg_2));
    assert (!zmsg_eq (msg, NULL));
    assert (!zmsg_eq (NULL, empty_msg));
    assert (!zmsg_eq (NULL, NULL));
    zmsg_destroy (&msg);
    zmsg_destroy (&msg_other);
    zmsg_destroy (&msg_dup);
    zmsg_destroy (&empty_msg);
    zmsg_destroy (&empty_msg_2);

    //  Test signal messages
    msg = zmsg_new_signal (0);
    assert (zmsg_signal (msg) == 0);
    zmsg_destroy (&msg);
    msg = zmsg_new_signal (-1);
    assert (zmsg_signal (msg) == 255);
    zmsg_destroy (&msg);

    //  Now try methods on an empty message
    msg = zmsg_new ();
    assert (msg);
    assert (zmsg_size (msg) == 0);
    assert (zmsg_unwrap (msg) == NULL);
    assert (zmsg_first (msg) == NULL);
    assert (zmsg_last (msg) == NULL);
    assert (zmsg_next (msg) == NULL);
    assert (zmsg_pop (msg) == NULL);
    //  Sending an empty message is valid and destroys the message
    assert (zmsg_send (&msg, output) == 0);
    assert (!msg);

    zsock_destroy (&input);
    zsock_destroy (&output);

    //  @end
    printf ("OK\n");
}
コード例 #30
0
ファイル: zyre_node.c プロジェクト: opedroso/zyre
static void
zyre_node_recv_peer (zyre_node_t *self)
{
    //  Router socket tells us the identity of this peer
    zre_msg_t *msg = zre_msg_recv (self->inbox);
    if (!msg)
        return;                 //  Interrupted

    //  First frame is sender identity
    byte *peerid_data = zframe_data (zre_msg_routing_id (msg));
    size_t peerid_size = zframe_size (zre_msg_routing_id (msg));

    //  Identity must be [1] followed by 16-byte UUID
    if (peerid_size != ZUUID_LEN + 1) {
        zre_msg_destroy (&msg);
        return;
    }
    zuuid_t *uuid = zuuid_new ();
    zuuid_set (uuid, peerid_data + 1);

    //  On HELLO we may create the peer if it's unknown
    //  On other commands the peer must already exist
    zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid));
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        if (peer) {
            //  Remove fake peers
            if (zyre_peer_ready (peer)) {
                zyre_node_remove_peer (self, peer);
                assert (!(zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid)));
            }
            else
            if (streq (zyre_peer_endpoint (peer), self->endpoint)) {
                //  We ignore HELLO, if peer has same endpoint as current node
                zre_msg_destroy (&msg);
                zuuid_destroy (&uuid);
                return;
            }
        }
        peer = zyre_node_require_peer (self, uuid, zre_msg_endpoint (msg));
        assert (peer);
        zyre_peer_set_ready (peer, true);
    }
    //  Ignore command if peer isn't ready
    if (peer == NULL || !zyre_peer_ready (peer)) {
        zre_msg_destroy (&msg);
        zuuid_destroy (&uuid);
        return;
    }
    if (zyre_peer_messages_lost (peer, msg)) {
        zsys_warning ("(%s) messages lost from %s", self->name, zyre_peer_name (peer));
        zyre_node_remove_peer (self, peer);
        zre_msg_destroy (&msg);
        zuuid_destroy (&uuid);
        return;
    }
    //  Now process each command
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        //  Store properties from HELLO command into peer
        zyre_peer_set_name (peer, zre_msg_name (msg));
        zyre_peer_set_headers (peer, zre_msg_headers (msg));

        //  Tell the caller about the peer
        zstr_sendm (self->outbox, "ENTER");
        zstr_sendm (self->outbox, zyre_peer_identity (peer));
        zstr_sendm (self->outbox, zyre_peer_name (peer));
        zframe_t *headers = zhash_pack (zyre_peer_headers (peer));
        zframe_send (&headers, self->outbox, ZFRAME_MORE);
        zstr_send (self->outbox, zre_msg_endpoint (msg));

        if (self->verbose)
            zsys_info ("(%s) ENTER name=%s endpoint=%s",
                self->name, zyre_peer_name (peer), zyre_peer_endpoint (peer));

        //  Join peer to listed groups
        const char *name = zre_msg_groups_first (msg);
        while (name) {
            zyre_node_join_peer_group (self, peer, name);
            name = zre_msg_groups_next (msg);
        }
        //  Now take peer's status from HELLO, after joining groups
        zyre_peer_set_status (peer, zre_msg_status (msg));
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_WHISPER) {
        //  Pass up to caller API as WHISPER event
        zstr_sendm (self->outbox, "WHISPER");
        zstr_sendm (self->outbox, zuuid_str (uuid));
        zstr_sendm (self->outbox, zyre_peer_name (peer));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->outbox);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_SHOUT) {
        //  Pass up to caller as SHOUT event
        zstr_sendm (self->outbox, "SHOUT");
        zstr_sendm (self->outbox, zuuid_str (uuid));
        zstr_sendm (self->outbox, zyre_peer_name (peer));
        zstr_sendm (self->outbox, zre_msg_group (msg));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->outbox);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_PING) {
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK);
        zyre_peer_send (peer, &msg);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_JOIN) {
        zyre_node_join_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_LEAVE) {
        zyre_node_leave_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    zuuid_destroy (&uuid);
    zre_msg_destroy (&msg);

    //  Activity from peer resets peer timers
    zyre_peer_refresh (peer, self->evasive_timeout, self->expired_timeout);
}