static int process_meta_information_and_handle_heartbeat(subscriber_state_t *state, zmsg_t* msg) { zframe_t *first = zmsg_first(msg); char *pub_spec = NULL; bool is_heartbeat = zframe_streq(first, "heartbeat"); msg_meta_t meta; int rc = msg_extract_meta_info(msg, &meta); if (!rc) { // dump_meta_info(&meta); if (!state->meta_info_failures++) fprintf(stderr, "[E] subscriber: received invalid meta info\n"); return is_heartbeat; } if (meta.device_number == 0) { // ignore device number 0 state->messages_dev_zero++; return is_heartbeat; } if (is_heartbeat) { if (debug) printf("received heartbeat from device %d\n", meta.device_number); zmsg_first(msg); // msg_extract_meta_info repositions the pointer, so reset zframe_t *spec_frame = zmsg_next(msg); pub_spec = zframe_strdup(spec_frame); } state->message_gap_size += device_tracker_calculate_gap(state->tracker, &meta, pub_spec); return is_heartbeat; }
/* ================ download_data() ================ */ int download_data(zsock_t *sock, const char *key) { /* ---------------- Send Message ---------------- */ zmsg_t *download_msg = create_action_message(MSG_ACTION_GET); message_add_key_data(download_msg, key, "", 0); zmsg_send(&download_msg, sock); /* ---------------- Receive Message ---------------- */ zmsg_t *recv_msg = zmsg_recv(sock); if ( recv_msg == NULL ){ return -2; } /*zmsg_print(recv_msg);*/ int rc = -1; if (message_check_status(recv_msg, MSG_STATUS_WORKER_NOTFOUND) == 0 ){ warning_log("Not Found. key=%s", key); rc = 0; } else if ( message_check_status(recv_msg, MSG_STATUS_WORKER_ERROR) == 0 ){ error_log("Return MSG_STATUS_WORKER_ERROR. key=%s", key); rc = -1; } else { /*zmsg_print(recv_msg);*/ zframe_t *frame_msgtype = zmsg_first(recv_msg); if ( frame_msgtype != NULL ){ int16_t msgtype = *(int16_t*)zframe_data(frame_msgtype); if ( msgtype == MSGTYPE_DATA ){ zmsg_first(recv_msg); zframe_t *frame_key = zmsg_next(recv_msg); UNUSED const char *key = (const char *)zframe_data(frame_key); zframe_t *frame_data = zmsg_next(recv_msg); UNUSED const char *data = (const char *)zframe_data(frame_data); UNUSED uint32_t data_size = zframe_size(frame_data); /*notice_log("Receive key:%s data_size:%d", key, data_size);*/ rc = 0; } } } zmsg_destroy(&recv_msg); return rc; }
size_t zmsg_encode (zmsg_t *self, byte **buffer) { assert (self); assert (zmsg_is (self)); // Calculate real size of buffer size_t buffer_size = 0; zframe_t *frame = zmsg_first (self); while (frame) { size_t frame_size = zframe_size (frame); if (frame_size < 255) buffer_size += frame_size + 1; else buffer_size += frame_size + 1 + 4; frame = zmsg_next (self); } *buffer = (byte *) zmalloc (buffer_size); if (*buffer) { // Encode message now byte *dest = *buffer; frame = zmsg_first (self); while (frame) { size_t frame_size = zframe_size (frame); if (frame_size < 255) { *dest++ = (byte) frame_size; memcpy (dest, zframe_data (frame), frame_size); dest += frame_size; } else { *dest++ = 0xFF; *dest++ = (frame_size >> 24) & 255; *dest++ = (frame_size >> 16) & 255; *dest++ = (frame_size >> 8) & 255; *dest++ = frame_size & 255; memcpy (dest, zframe_data (frame), frame_size); dest += frame_size; } frame = zmsg_next (self); } assert ((dest - *buffer) == buffer_size); } return buffer_size; }
int message_check_status(zmsg_t *msg, const char *status) { int16_t msgtype = message_get_msgtype(msg); if ( msgtype == MSGTYPE_STATUS ){ zmsg_first(msg); zframe_t *frame = zmsg_next(msg); if ( frame != NULL ){ return memcmp(zframe_data(frame), status, strlen(status)); } } return -1; }
int message_check_heartbeat(zmsg_t *msg, const char *heartbeat) { int16_t msgtype = message_get_msgtype(msg); if ( msgtype == MSGTYPE_HEARTBEAT ){ zmsg_first(msg); zframe_t *frame = zmsg_next(msg); if ( frame != NULL ){ return memcmp(zframe_data(frame), heartbeat, strlen(heartbeat)); } } return -1; }
int message_check_action(zmsg_t *msg, const char *action) { int16_t msgtype = message_get_msgtype(msg); if ( msgtype == MSGTYPE_ACTION ){ zmsg_first(msg); zframe_t *frame = zmsg_next(msg); if ( frame != NULL ){ return memcmp(zframe_data(frame), action, strlen(action)); } } return -1; }
void interval_minit (interval_t ** interval, zmsg_t * msg) { *interval = malloc (sizeof (interval_t)); zframe_t *frame = zmsg_first (msg); memcpy (&((*interval)->start), zframe_data (frame), zframe_size (frame)); frame = zmsg_next (msg); memcpy (&((*interval)->end), zframe_data (frame), zframe_size (frame)); }
void zmsg_print (zmsg_t *self) { assert (self); assert (zmsg_is (self)); if (!self) { zsys_debug ("(NULL)"); return; } zframe_t *frame = zmsg_first (self); while (frame) { zframe_print (frame, NULL); frame = zmsg_next (self); } }
// -------------------------------------------------------------------------- // Save message to an open file, return 0 if OK, else -1. int zmsg_save (zmsg_t *self, FILE *file) { assert (self); assert (file); zframe_t *frame = zmsg_first (self); while (frame) { size_t frame_size = zframe_size (frame); if (fwrite (&frame_size, sizeof (frame_size), 1, file) != 1) return -1; if (fwrite (zframe_data (frame), frame_size, 1, file) != 1) return -1; frame = zmsg_next (self); } return 0; }
void zmsg_fprint (zmsg_t *self, FILE *file) { assert (self); assert (zmsg_is (self)); fprintf (file, "--------------------------------------\n"); if (!self) { fprintf (file, "NULL"); return; } zframe_t *frame = zmsg_first (self); int frame_nbr = 0; while (frame && frame_nbr++ < 10) { zframe_fprint (frame, NULL, file); frame = zmsg_next (self); } }
zgossip_msg_t * zgossip_msg_recv_nowait (void *input) { assert (input); zmsg_t *msg = zmsg_recv_nowait (input); // If message came from a router socket, first frame is routing_id zframe_t *routing_id = NULL; if (zsocket_type (zsock_resolve (input)) == ZMQ_ROUTER) { routing_id = zmsg_pop (msg); // If message was not valid, forget about it if (!routing_id || !zmsg_next (msg)) return NULL; // Malformed or empty } zgossip_msg_t * zgossip_msg = zgossip_msg_decode (&msg); if (zsocket_type (zsock_resolve (input)) == ZMQ_ROUTER) zgossip_msg->routing_id = routing_id; return zgossip_msg; }
zmsg_t * zmsg_dup (zmsg_t *self) { assert (self); assert (zmsg_is (self)); zmsg_t *copy = zmsg_new (); if (!copy) return NULL; zframe_t *frame = zmsg_first (self); while (frame) { if (zmsg_addmem (copy, zframe_data (frame), zframe_size (frame))) { zmsg_destroy (©); return NULL; } frame = zmsg_next (self); } return copy; }
platanos_node_t * platanos_connect (platanos_t * platanos, zmsg_t * msg) { char bind_point[50]; zframe_t *frame = zmsg_next (msg); memcpy (bind_point, zframe_data (frame), zframe_size (frame)); zmsg_destroy (&msg); int rc; rc = zsocket_connect (platanos->router, "%s", bind_point); assert (rc == 0); platanos_node_t *node; platanos_node_init (&node); strcpy (node->bind_point, bind_point); return node; }
zmsg_t * zmsg_dup (zmsg_t *self) { if (self) { assert (zmsg_is (self)); zmsg_t *copy = zmsg_new (); if (copy) { zframe_t *frame = zmsg_first (self); while (frame) { if (zmsg_addmem (copy, zframe_data (frame), zframe_size (frame))) { zmsg_destroy (©); break; // Abandon attempt to copy message } frame = zmsg_next (self); } } return copy; } else return NULL; }
size_t zmsg_encode (zmsg_t *self, byte **buffer) { assert (self); // Calculate real size of buffer size_t buffer_size = 0; zframe_t *frame = zmsg_first (self); while (frame) { size_t frame_size = zframe_size (frame); if (frame_size < ZMSG_SHORT_LEN) buffer_size += frame_size + 1; else if (frame_size < 0x10000) buffer_size += frame_size + 3; else buffer_size += frame_size + 5; frame = zmsg_next (self); } *buffer = malloc (buffer_size); // Encode message now byte *dest = *buffer; frame = zmsg_first (self); while (frame) { size_t frame_size = zframe_size (frame); if (frame_size < ZMSG_SHORT_LEN) { *dest++ = (byte) frame_size; memcpy (dest, zframe_data (frame), frame_size); dest += frame_size; } else if (frame_size < 0x10000) { *dest++ = ZMSG_SHORT_LEN; *dest++ = (frame_size >> 8) & 255; *dest++ = frame_size & 255; memcpy (dest, zframe_data (frame), frame_size); dest += frame_size; } else {
int PrimeWorker::HandleInput(zmq_pollitem_t *item) { zmsg_t* msg = zmsg_recv(item->socket); zframe_t* frame = zmsg_next(msg); size_t fsize = zframe_size(frame); const byte* fbytes = zframe_data(frame); proto::Signal& sig = mSignal; sig.ParseFromArray(fbytes+1, fsize-1); if(sig.type() == proto::Signal::NEWBLOCK){ mCurrBlock = sig.block(); mCurrHeight = mCurrBlock.height(); //printf("HandleInput(): proto::Signal::NEWBLOCK %d\n", mCurrHeight); zmsg_send(&msg, mSignals); while(true){ while(vNodes.empty()) MilliSleep(1000); mIndexPrev = pindexBest; if(!mIndexPrev) MilliSleep(1000); else break; } mWorkerCount = mNonceMap.size(); mNonceMap.clear(); mReqNonces.clear(); mShares.clear(); if(mBlockTemplate) delete mBlockTemplate; mBlockTemplate = CreateNewBlock(mReserveKey); if(!mBlockTemplate){ printf("ERROR: CreateNewBlock() failed.\n"); return -1; } }else if(sig.type() == proto::Signal::SHUTDOWN){ printf("HandleInput(): proto::Signal::SHUTDOWN\n"); zmsg_send(&msg, mSignals); FlushStats(); return -1; } zmsg_destroy(&msg); return 0; }
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"); }
int rrwrk_start(rrwrk_t *self, wrk_task_fn *cb) { self->heartbeat_at = zclock_time() + self->heartbeat; self->cb = cb; //** Start task thread and wait for synchronization signal self->pipe = zthread_fork(self->ctx, rrtask_manager_fn, (void *)self); assert(self->pipe); free(zstr_recv(self->pipe)); //self->liveness = HEARTBEAT_LIVENESS; //** Don't do reconnect before the first connection established while(!zctx_interrupted) { zmq_pollitem_t items[] = {{self->worker, 0, ZMQ_POLLIN, 0}, {self->pipe, 0, ZMQ_POLLIN, 0}}; //** Be aware: this must be within while loop!! int rc = zmq_poll(items, 2, self->heartbeat * ZMQ_POLL_MSEC); if (rc == -1) break; //** Interrupted if (items[0].revents & ZMQ_POLLIN) { //** Data from broker is ready zmsg_t *msg = zmsg_recv(self->worker); if (!msg) break; //** Interrupted. Need to do more research to confirm it self->liveness = HEARTBEAT_LIVENESS; self->last_heartbeat = zclock_time(); //** Dont try to handle errors, just assert noisily assert(zmsg_size(msg) >= 3); //** empty + header + command + ... zframe_t *empty = zmsg_pop(msg); assert(zframe_streq(empty, "")); zframe_destroy(&empty); zframe_t *header = zmsg_pop(msg); assert(zframe_streq(header, RR_WORKER)); zframe_destroy(&header); zframe_t *command = zmsg_pop(msg); if (zframe_streq(command, RRWRK_REQUEST)) { assert(zmsg_size(msg) == 3); //** UUID + SOURCE + INPUT DATA self->total_received++; zmq_pollitem_t item = {self->pipe, 0, ZMQ_POLLOUT, 0}; int rc = zmq_poll(&item, 1, 0); assert(rc != -1); if (item.revents & ZMQ_POLLOUT) { //** Dispatch it if worker is ready //** Send task to task manager zmsg_send(&msg, self->pipe); } else { //** Otherwise put it on waiting list zlist_push(self->data, zmsg_dup(msg)); } } else if (zframe_streq(command, RRWRK_HEARTBEAT)) { ; //** Do nothing for heartbeat } else if (zframe_streq(command, RRWRK_DISCONNECT)) { rrwrk_connect_to_broker(self); } else { log_printf(0, "E: invalid input message\n"); } zframe_destroy(&command); zmsg_destroy(&msg); } else if ((zclock_time() - self->heartbeat) > self->last_heartbeat) { if(--self->liveness == 0) { rrwrk_print(self); log_printf(0, "W: Disconnected from broker - retrying ...\n"); rrwrk_print(self); zclock_sleep(self->reconnect); rrwrk_connect_to_broker(self); } } if (items[1].revents & ZMQ_POLLIN) { //** Data from pipe is ready zmsg_t *output = zmsg_recv(self->pipe); assert(zmsg_size(output) == 3); //** UUID + SOURCE + DATA self->total_finished++; zmsg_t *reply = zmsg_new(); //** Adds UUID + SOURCE to reply message zframe_t *uuid = zframe_dup(zmsg_first(output)); zframe_t *source = zframe_dup(zmsg_next(output)); zmsg_add(reply, uuid); zmsg_add(reply, source); //** Sends reply to broker rrwrk_send_to_broker(self, RRWRK_REPLY, reply); //** Sends output to sinker //zmsg_send(&output, self->sender); rrwrk_send_to_sinker(self, RRWRK_OUTPUT, output); zmsg_destroy(&output); zmsg_destroy(&reply); } //** Dispatch task if any while (true) { zmq_pollitem_t pipe_write = {self->pipe, 0, ZMQ_POLLOUT, 0}; zmq_poll(&pipe_write, 1, 0); if ((pipe_write.revents & ZMQ_POLLOUT) && (zlist_size(self->data))) { zmsg_t* data = (zmsg_t *)zlist_pop(self->data); zmsg_send(&data, self->pipe); printf("Dispatched one task.\n"); } else break; } //** Send HEARTBEAT if it's time if (zclock_time() > self->heartbeat_at) { rrwrk_print(self); rrwrk_send_to_broker(self, RRWRK_HEARTBEAT, NULL); self->heartbeat_at = zclock_time() + self->heartbeat; } } if (zctx_interrupted) log_printf(0, "W: interrupt received. Killing worker...\n"); return -1; }
Z K1(zmsgnext){PC(x); P(zmsg_size(VSK(x))>0, ptr(zmsg_next(VSK(x)))); R krr("empty");}
int mdp_client_msg_send (mdp_client_msg_t *self, zsock_t *output) { assert (self); assert (output); if (zsock_type (output) == ZMQ_ROUTER) zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE); size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case MDP_CLIENT_MSG_CLIENT_REQUEST: frame_size += 1 + strlen ("MDPC02"); frame_size += 1; // messageid frame_size += 1 + strlen (self->service); break; case MDP_CLIENT_MSG_CLIENT_PARTIAL: frame_size += 1 + strlen ("MDPC02"); frame_size += 1; // messageid frame_size += 1 + strlen (self->service); break; case MDP_CLIENT_MSG_CLIENT_FINAL: frame_size += 1 + strlen ("MDPC02"); frame_size += 1; // messageid frame_size += 1 + strlen (self->service); break; } // Now serialize message into the frame zmq_msg_t frame; zmq_msg_init_size (&frame, frame_size); self->needle = (byte *) zmq_msg_data (&frame); PUT_NUMBER2 (0xAAA0 | 4); PUT_NUMBER1 (self->id); bool send_body = false; size_t nbr_frames = 1; // Total number of frames to send switch (self->id) { case MDP_CLIENT_MSG_CLIENT_REQUEST: PUT_STRING ("MDPC02"); PUT_NUMBER1 (1); PUT_STRING (self->service); nbr_frames += self->body? zmsg_size (self->body): 1; send_body = true; break; case MDP_CLIENT_MSG_CLIENT_PARTIAL: PUT_STRING ("MDPC02"); PUT_NUMBER1 (2); PUT_STRING (self->service); nbr_frames += self->body? zmsg_size (self->body): 1; send_body = true; break; case MDP_CLIENT_MSG_CLIENT_FINAL: PUT_STRING ("MDPC02"); PUT_NUMBER1 (3); PUT_STRING (self->service); nbr_frames += self->body? zmsg_size (self->body): 1; send_body = true; break; } // Now send the data frame zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0); // Now send the body if necessary if (send_body) { if (self->body) { zframe_t *frame = zmsg_first (self->body); while (frame) { zframe_send (&frame, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0)); frame = zmsg_next (self->body); } } else zmq_send (zsock_resolve (output), NULL, 0, 0); } return 0; }
/// // Return the next frame. If there are no more frames, returns NULL. To move // to the first frame call zmsg_first(). Advances the cursor. QmlZframe *QmlZmsg::next () { QmlZframe *retQ_ = new QmlZframe (); retQ_->self = zmsg_next (self); return retQ_; };
int zproto_example_send (zproto_example_t *self, zsock_t *output) { assert (self); assert (output); if (zsock_type (output) == ZMQ_ROUTER) zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE); size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case ZPROTO_EXAMPLE_LOG: frame_size += 2; // sequence frame_size += 2; // version frame_size += 1; // level frame_size += 1; // event frame_size += 2; // node frame_size += 2; // peer frame_size += 8; // time frame_size += 1 + strlen (self->host); frame_size += 4; if (self->data) frame_size += strlen (self->data); break; case ZPROTO_EXAMPLE_STRUCTURES: frame_size += 2; // sequence frame_size += 4; // Size is 4 octets if (self->aliases) { char *aliases = (char *) zlist_first (self->aliases); while (aliases) { frame_size += 4 + strlen (aliases); aliases = (char *) zlist_next (self->aliases); } } frame_size += 4; // Size is 4 octets if (self->headers) { self->headers_bytes = 0; char *item = (char *) zhash_first (self->headers); while (item) { self->headers_bytes += 1 + strlen (zhash_cursor (self->headers)); self->headers_bytes += 4 + strlen (item); item = (char *) zhash_next (self->headers); } } frame_size += self->headers_bytes; break; case ZPROTO_EXAMPLE_BINARY: frame_size += 2; // sequence frame_size += 4; // flags frame_size += 4; // Size is 4 octets if (self->public_key) frame_size += zchunk_size (self->public_key); frame_size += ZUUID_LEN; // identifier break; case ZPROTO_EXAMPLE_TYPES: frame_size += 2; // sequence frame_size += 1 + strlen (self->client_forename); frame_size += 1 + strlen (self->client_surname); frame_size += 1 + strlen (self->client_mobile); frame_size += 1 + strlen (self->client_email); frame_size += 1 + strlen (self->supplier_forename); frame_size += 1 + strlen (self->supplier_surname); frame_size += 1 + strlen (self->supplier_mobile); frame_size += 1 + strlen (self->supplier_email); break; } // Now serialize message into the frame zmq_msg_t frame; zmq_msg_init_size (&frame, frame_size); self->needle = (byte *) zmq_msg_data (&frame); PUT_NUMBER2 (0xAAA0 | 0); PUT_NUMBER1 (self->id); bool have_content = false; size_t nbr_frames = 1; // Total number of frames to send switch (self->id) { case ZPROTO_EXAMPLE_LOG: PUT_NUMBER2 (self->sequence); PUT_NUMBER2 (3); PUT_NUMBER1 (self->level); PUT_NUMBER1 (self->event); PUT_NUMBER2 (self->node); PUT_NUMBER2 (self->peer); PUT_NUMBER8 (self->time); PUT_STRING (self->host); if (self->data) { PUT_LONGSTR (self->data); } else PUT_NUMBER4 (0); // Empty string break; case ZPROTO_EXAMPLE_STRUCTURES: PUT_NUMBER2 (self->sequence); if (self->aliases) { PUT_NUMBER4 (zlist_size (self->aliases)); char *aliases = (char *) zlist_first (self->aliases); while (aliases) { PUT_LONGSTR (aliases); aliases = (char *) zlist_next (self->aliases); } } else PUT_NUMBER4 (0); // Empty string array if (self->headers) { PUT_NUMBER4 (zhash_size (self->headers)); char *item = (char *) zhash_first (self->headers); while (item) { PUT_STRING (zhash_cursor (self->headers)); PUT_LONGSTR (item); item = (char *) zhash_next (self->headers); } } else PUT_NUMBER4 (0); // Empty hash break; case ZPROTO_EXAMPLE_BINARY: PUT_NUMBER2 (self->sequence); PUT_OCTETS (self->flags, 4); if (self->public_key) { PUT_NUMBER4 (zchunk_size (self->public_key)); memcpy (self->needle, zchunk_data (self->public_key), zchunk_size (self->public_key)); self->needle += zchunk_size (self->public_key); } else PUT_NUMBER4 (0); // Empty chunk if (self->identifier) zuuid_export (self->identifier, self->needle); else memset (self->needle, 0, ZUUID_LEN); self->needle += ZUUID_LEN; nbr_frames++; nbr_frames += self->content? zmsg_size (self->content): 1; have_content = true; break; case ZPROTO_EXAMPLE_TYPES: PUT_NUMBER2 (self->sequence); PUT_STRING (self->client_forename); PUT_STRING (self->client_surname); PUT_STRING (self->client_mobile); PUT_STRING (self->client_email); PUT_STRING (self->supplier_forename); PUT_STRING (self->supplier_surname); PUT_STRING (self->supplier_mobile); PUT_STRING (self->supplier_email); break; } // Now send the data frame zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0); // Now send any frame fields, in order if (self->id == ZPROTO_EXAMPLE_BINARY) { // If address isn't set, send an empty frame if (self->address) zframe_send (&self->address, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0)); else zmq_send (zsock_resolve (output), NULL, 0, (--nbr_frames? ZMQ_SNDMORE: 0)); } // Now send the content if necessary if (have_content) { if (self->content) { zframe_t *frame = zmsg_first (self->content); while (frame) { zframe_send (&frame, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0)); frame = zmsg_next (self->content); } } else zmq_send (zsock_resolve (output), NULL, 0, 0); } return 0; }
zre_msg_t * zre_msg_decode (zmsg_t **msg_p, int socket_type) { assert (msg_p); zmsg_t *msg = *msg_p; if (msg == NULL) return NULL; zre_msg_t *self = zre_msg_new (0); // If message came from a router socket, first frame is routing_id if (socket_type == ZMQ_ROUTER) { self->routing_id = zmsg_pop (msg); // If message was not valid, forget about it if (!self->routing_id || !zmsg_next (msg)) { zre_msg_destroy (&self); return (NULL); // Malformed or empty } } // Read and parse command in frame zframe_t *frame = zmsg_pop (msg); if (!frame) goto empty; // Malformed or empty // Get and check protocol signature self->needle = zframe_data (frame); self->ceiling = self->needle + zframe_size (frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 1)) goto empty; // Invalid signature // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZRE_MSG_HELLO: GET_NUMBER2 (self->sequence); GET_STRING (self->ipaddress); GET_NUMBER2 (self->mailbox); { size_t list_size; GET_NUMBER4 (list_size); self->groups = zlist_new (); zlist_autofree (self->groups); while (list_size--) { char *string; GET_LONGSTR (string); zlist_append (self->groups, string); free (string); } } GET_NUMBER1 (self->status); { size_t hash_size; GET_NUMBER4 (hash_size); self->headers = zhash_new (); zhash_autofree (self->headers); while (hash_size--) { char *key, *value; GET_STRING (key); GET_LONGSTR (value); zhash_insert (self->headers, key, value); free (key); free (value); } } break; case ZRE_MSG_WHISPER: GET_NUMBER2 (self->sequence); // Get zero or more remaining frames, leaving current // frame untouched self->content = zmsg_new (); while (zmsg_size (msg)) zmsg_add (self->content, zmsg_pop (msg)); break; case ZRE_MSG_SHOUT: GET_NUMBER2 (self->sequence); GET_STRING (self->group); // Get zero or more remaining frames, leaving current // frame untouched self->content = zmsg_new (); while (zmsg_size (msg)) zmsg_add (self->content, zmsg_pop (msg)); break; case ZRE_MSG_JOIN: GET_NUMBER2 (self->sequence); GET_STRING (self->group); GET_NUMBER1 (self->status); break; case ZRE_MSG_LEAVE: GET_NUMBER2 (self->sequence); GET_STRING (self->group); GET_NUMBER1 (self->status); break; case ZRE_MSG_PING: GET_NUMBER2 (self->sequence); break; case ZRE_MSG_PING_OK: GET_NUMBER2 (self->sequence); break; default: goto malformed; } // Successful return zframe_destroy (&frame); zmsg_destroy (msg_p); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zmsg_destroy (msg_p); zre_msg_destroy (&self); return (NULL); }
/// // Return the next frame. If there are no more frames, returns NULL. To move // to the first frame call zmsg_first(). Advances the cursor. QZframe * QZmsg::next () { QZframe *rv = new QZframe (zmsg_next (self)); return rv; }
int xrap_traffic_send (xrap_traffic_t *self, zsock_t *output) { assert (self); assert (output); if (zsock_type (output) == ZMQ_ROUTER) zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE); size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case XRAP_TRAFFIC_CONNECTION_OPEN: frame_size += 1 + strlen ("MALAMUTE"); frame_size += 2; // version frame_size += 1 + strlen (self->address); break; case XRAP_TRAFFIC_XRAP_SEND: frame_size += 4; // timeout break; case XRAP_TRAFFIC_XRAP_OFFER: frame_size += 1 + strlen (self->route); frame_size += 1 + strlen (self->method); break; case XRAP_TRAFFIC_XRAP_DELIVER: frame_size += ZUUID_LEN; // sender break; case XRAP_TRAFFIC_OK: frame_size += 2; // status_code frame_size += 1 + strlen (self->status_reason); break; case XRAP_TRAFFIC_FAIL: frame_size += 2; // status_code frame_size += 1 + strlen (self->status_reason); break; case XRAP_TRAFFIC_ERROR: frame_size += 2; // status_code frame_size += 1 + strlen (self->status_reason); break; } // Now serialize message into the frame zmq_msg_t frame; zmq_msg_init_size (&frame, frame_size); self->needle = (byte *) zmq_msg_data (&frame); PUT_NUMBER2 (0xAAA0 | 9); PUT_NUMBER1 (self->id); bool have_content = false; size_t nbr_frames = 1; // Total number of frames to send switch (self->id) { case XRAP_TRAFFIC_CONNECTION_OPEN: PUT_STRING ("MALAMUTE"); PUT_NUMBER2 (1); PUT_STRING (self->address); break; case XRAP_TRAFFIC_XRAP_SEND: PUT_NUMBER4 (self->timeout); nbr_frames += self->content? zmsg_size (self->content): 1; have_content = true; break; case XRAP_TRAFFIC_XRAP_OFFER: PUT_STRING (self->route); PUT_STRING (self->method); break; case XRAP_TRAFFIC_XRAP_DELIVER: if (self->sender) zuuid_export (self->sender, self->needle); else memset (self->needle, 0, ZUUID_LEN); self->needle += ZUUID_LEN; nbr_frames += self->content? zmsg_size (self->content): 1; have_content = true; break; case XRAP_TRAFFIC_OK: PUT_NUMBER2 (self->status_code); PUT_STRING (self->status_reason); break; case XRAP_TRAFFIC_FAIL: PUT_NUMBER2 (self->status_code); PUT_STRING (self->status_reason); break; case XRAP_TRAFFIC_ERROR: PUT_NUMBER2 (self->status_code); PUT_STRING (self->status_reason); break; } // Now send the data frame zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0); // Now send the content if necessary if (have_content) { if (self->content) { zframe_t *frame = zmsg_first (self->content); while (frame) { zframe_send (&frame, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0)); frame = zmsg_next (self->content); } } else zmq_send (zsock_resolve (output), NULL, 0, 0); } return 0; }