int main (int argc, char *argv []) { zctx_t *ctx = zctx_new (); // Use the CZMQ zbeacon class to make sure we listen on the // same network interface as our peers void *collector = zsocket_new (ctx, ZMQ_SUB); zbeacon_t *beacon = zbeacon_new (ZRE_DISCOVERY_PORT); char *host = zbeacon_hostname (beacon); // Bind to an ephemeral port int port = zsocket_bind (collector, "tcp://%s:*", host); // Announce this to all peers we connect to zre_node_t *node = zre_node_new (); zre_node_header_set (node, "X-ZRELOG", "tcp://%s:%d", host, port); // Get all log messages (don't filter) zsocket_set_subscribe (collector, ""); zmq_pollitem_t pollitems [] = { { collector, 0, ZMQ_POLLIN, 0 }, { zre_node_handle (node), 0, ZMQ_POLLIN, 0 } }; while (!zctx_interrupted) { if (zmq_poll (pollitems, 2, 1000 * ZMQ_POLL_MSEC) == -1) break; // Interrupted // Handle input on collector if (pollitems [0].revents & ZMQ_POLLIN) s_print_log_msg (collector); // Handle event from node (ignore it) if (pollitems [1].revents & ZMQ_POLLIN) { zmsg_t *msg = zre_node_recv (node); if (!msg) break; // Interrupted zmsg_destroy (&msg); } } zre_node_destroy (&node); zbeacon_destroy (&beacon); zctx_destroy (&ctx); return 0; }
static void interface_task (void *args, zctx_t *ctx, void *pipe ) { lsd_handle_t *self = (lsd_handle_t*) args; assert(self); char *peer = NULL; char *group = NULL; zframe_t* msg_frame = NULL; zmq_pollitem_t pollitems [] = { { pipe, 0, ZMQ_POLLIN, 0 }, { zre_node_handle (self->interface), 0, ZMQ_POLLIN, 0 } }; while (!zctx_interrupted) { if (zmq_poll (pollitems, 2, randof (1000) * ZMQ_POLL_MSEC) == -1) { debugLog ("I: Interrupted by user action.\n"); break; // Interrupted } if (pollitems [0].revents & ZMQ_POLLIN) { debugLog ("I: Interrupted by parent.\n"); break; // Any command fom parent means EXIT } // Process an event from interface if (pollitems [1].revents & ZMQ_POLLIN) { zmsg_t *incoming = zre_node_recv (self->interface); if (!incoming) { debugLog ("I: Interrupted before end of read.\n"); break; // Interrupted } char *event = zmsg_popstr (incoming); debugLog("I EVENT == %s", event); if (streq (event, "ENTER")) { peer = zmsg_popstr (incoming); debugLog ("I: ENTER '%s'", peer); if(self->callback) { (*self->callback)(self, LSD_EVENT_ENTER, peer, NULL, NULL, 0, self->class_ptr); } } else if (streq (event, "EXIT")) { peer = zmsg_popstr (incoming); debugLog ("I: EXIT '%s'", peer); if(self->callback) { (*self->callback)(self, LSD_EVENT_EXIT, peer, NULL, NULL, 0, self->class_ptr); } } else if (streq (event, "WHISPER")) { peer = zmsg_popstr (incoming); msg_frame = zmsg_pop (incoming); debugLog ("I: WHISPER '%s' msglen %d", peer, (int)zframe_size(msg_frame)); if(self->callback) { (*self->callback)(self, LSD_EVENT_WHISPER, peer, NULL, (const uint8_t*)zframe_data(msg_frame), zframe_size(msg_frame), self->class_ptr); } } else if (streq (event, "SHOUT")) { peer = zmsg_popstr (incoming); group = zmsg_popstr (incoming); msg_frame = zmsg_pop (incoming); debugLog ("I: SHOUT from '%s' group '%s' msglen %d", peer, group, (int)zframe_size(msg_frame)); if(self->callback) { (*self->callback)(self, LSD_EVENT_SHOUT, peer, group, zframe_data(msg_frame), zframe_size(msg_frame), self->class_ptr); } } else if (streq (event, "DELIVER")) { char *filename = zmsg_popstr (incoming); char *fullname = zmsg_popstr (incoming); debugLog ("I: DELIVER file %s", fullname); if(self->callback) { (*self->callback)(self, LSD_EVENT_DELIVER, NULL, NULL, (const uint8_t*)fullname, strlen(fullname), self->class_ptr); } free (fullname); free (filename); }else if (streq (event, "JOIN")) { peer = zmsg_popstr (incoming); group = zmsg_popstr (incoming); debugLog ("I: JOIN '%s - %s'", peer, group); if(self->callback) { (*self->callback)(self, LSD_EVENT_JOIN, peer, group, NULL, 0, self->class_ptr); } } else if (streq (event, "LEAVE")) { peer = zmsg_popstr (incoming); group = zmsg_popstr (incoming); debugLog ("I: LEAVE '%s - %s'", peer, group); if(self->callback) { (*self->callback)(self, LSD_EVENT_LEAVE, peer, group, NULL, 0, self->class_ptr); } } if(peer) { free(peer); peer = NULL; } if(group) { free(group); group = NULL; } if(msg_frame) { zframe_destroy(&msg_frame); msg_frame = NULL; } free (event); zmsg_destroy (&incoming); } } }
int main (int argc, char *argv []) { // Get number of remote nodes to simulate, default 100 // If we run multiple zre_perf_remote on multiple machines, // max_node must be sum of all the remote node counts. int max_node = 100; int max_message = 10000; int nbr_node = 0; int nbr_hello_response = 0; int nbr_message = 0; int nbr_message_response = 0; if (argc > 1) max_node = atoi (argv [1]); if (argc > 2) max_message = atoi (argv [2]); zre_node_t *node = zre_node_new (); zre_node_join (node, "GLOBAL"); int64_t start = zclock_time (); int64_t elapse; char **peers = zmalloc (sizeof (char *) * max_node); while (true) { zmsg_t *incoming = zre_node_recv (node); if (!incoming) break; // Interrupted // If new peer, say hello to it and wait for it to answer us char *event = zmsg_popstr (incoming); if (streq (event, "ENTER")) { char *peer = zmsg_popstr (incoming); peers[nbr_node++] = peer; if (nbr_node == max_node) { // got HELLO from the all remote nodes elapse = zclock_time () - start; printf ("Took %ld ms to coordinate with all remote\n", (long)elapse); } } else if (streq (event, "WHISPER")) { char *peer = zmsg_popstr (incoming); char *cookie = zmsg_popstr (incoming); if (streq (cookie, "R:HELLO")) { if (++nbr_hello_response == max_node) { // got HELLO from the all remote nodes elapse = zclock_time () - start; printf ("Took %ld ms to get greeting from all remote\n", (long)elapse); } } free (peer); free (cookie); } free (event); zmsg_destroy (&incoming); if (nbr_node == max_node && nbr_hello_response == max_node) break; } zmq_pollitem_t pollitems [] = { { zre_node_handle (node), 0, ZMQ_POLLIN, 0 } }; // send WHISPER message start = zclock_time (); for (nbr_message = 0; nbr_message < max_message; nbr_message++) { zmsg_t *outgoing = zmsg_new (); zmsg_addstr (outgoing, peers [nbr_message % max_node]); zmsg_addstr (outgoing, "S:WHISPER"); zre_node_whisper (node, &outgoing); while (zmq_poll (pollitems, 1, 0) > 0) { if (s_node_recv (node, "WHISPER", "R:WHISPER")) nbr_message_response++; } } while (nbr_message_response < max_message) if (s_node_recv (node, "WHISPER", "R:WHISPER")) nbr_message_response++; // got WHISPER response from the all remote nodes elapse = zclock_time () - start; printf ("Took %ld ms to send/receive %d message. %.2f msg/s \n", (long)elapse, max_message, (float) max_message * 1000 / elapse); // send SPOUT message start = zclock_time (); nbr_message = 0; nbr_message_response = 0; max_message = max_message / max_node; for (nbr_message = 0; nbr_message < max_message; nbr_message++) { zmsg_t *outgoing = zmsg_new (); zmsg_addstr (outgoing, "GLOBAL"); zmsg_addstr (outgoing, "S:SHOUT"); zre_node_shout (node, &outgoing); while (zmq_poll (pollitems, 1, 0) > 0) { if (s_node_recv (node, "SHOUT", "R:SHOUT")) nbr_message_response++; } } while (nbr_message_response < max_message * max_node) if (s_node_recv (node, "SHOUT", "R:SHOUT")) nbr_message_response++; // got SHOUT response from the all remote nodes elapse = zclock_time () - start; printf ("Took %ld ms to send %d, recv %d GROUP message. %.2f msg/s \n", (long) elapse, max_message, max_node * max_message, (float) max_node * max_message * 1000 / elapse); zre_node_destroy (&node); for (nbr_node = 0; nbr_node < max_node; nbr_node++) { free (peers[nbr_node]); } free (peers); return 0; }
static void node_task (void *args, zctx_t *ctx, void *pipe) { zre_node_t *node = zre_node_new (); int64_t counter = 0; char *to_peer = NULL; // Either of these set, char *to_group = NULL; // and we set a message char *cookie = NULL; zmq_pollitem_t pollitems [] = { { pipe, 0, ZMQ_POLLIN, 0 }, { zre_node_handle (node), 0, ZMQ_POLLIN, 0 } }; // Do something once a second int64_t trigger = zclock_time () + 1000; while (!zctx_interrupted) { if (zmq_poll (pollitems, 2, randof (1000) * ZMQ_POLL_MSEC) == -1) break; // Interrupted if (pollitems [0].revents & ZMQ_POLLIN) break; // Any command from parent means EXIT // Process an event from node if (pollitems [1].revents & ZMQ_POLLIN) { zmsg_t *incoming = zre_node_recv (node); if (!incoming) break; // Interrupted char *event = zmsg_popstr (incoming); if (streq (event, "ENTER")) { // Always say hello to new peer to_peer = zmsg_popstr (incoming); } else if (streq (event, "EXIT")) { // Always try talk to departed peer to_peer = zmsg_popstr (incoming); } else if (streq (event, "WHISPER")) { // Send back response 1/2 the time if (randof (2) == 0) { to_peer = zmsg_popstr (incoming); cookie = zmsg_popstr (incoming); } } else if (streq (event, "SHOUT")) { to_peer = zmsg_popstr (incoming); to_group = zmsg_popstr (incoming); cookie = zmsg_popstr (incoming); // Send peer response 1/3rd the time if (randof (3) > 0) { free (to_peer); to_peer = NULL; } // Send group response 1/3rd the time if (randof (3) > 0) { free (to_group); to_group = NULL; } } else if (streq (event, "JOIN")) { char *from_peer = zmsg_popstr (incoming); char *group = zmsg_popstr (incoming); if (randof (3) > 0) { zre_node_join (node, group); } free (from_peer); free (group); } else if (streq (event, "LEAVE")) { char *from_peer = zmsg_popstr (incoming); char *group = zmsg_popstr (incoming); if (randof (3) > 0) { zre_node_leave (node, group); } free (from_peer); free (group); } else if (streq (event, "DELIVER")) { char *filename = zmsg_popstr (incoming); char *fullname = zmsg_popstr (incoming); printf ("I: received file %s\n", fullname); free (fullname); free (filename); } free (event); zmsg_destroy (&incoming); // Send outgoing messages if needed if (to_peer) { zmsg_t *outgoing = zmsg_new (); zmsg_addstr (outgoing, to_peer); zmsg_addstr (outgoing, "%lu", counter++); zre_node_whisper (node, &outgoing); free (to_peer); to_peer = NULL; } if (to_group) { zmsg_t *outgoing = zmsg_new (); zmsg_addstr (outgoing, to_group); zmsg_addstr (outgoing, "%lu", counter++); zre_node_shout (node, &outgoing); free (to_group); to_group = NULL; } if (cookie) { free (cookie); cookie = NULL; } } if (zclock_time () >= trigger) { trigger = zclock_time () + 1000; char group [10]; sprintf (group, "GROUP%03d", randof (MAX_GROUP)); if (randof (4) == 0) zre_node_join (node, group); else if (randof (3) == 0) zre_node_leave (node, group); } } zre_node_destroy (&node); }