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; }
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); }
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; }
/* 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; }
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); }
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; }
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; }
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); }
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; }
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); }
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); } }
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); }
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; }
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); }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
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; }
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; }
// 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); }
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; }
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; }
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"); }
/// // 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_; };
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 (©, 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 (©); 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"); }
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); }