static void * client_task (void *args) { void *context = zmq_init (1); void *client = zmq_socket (context, ZMQ_XREQ); // Generate printable identity for the client char identity [5]; sprintf (identity, "%04X", randof (0x10000)); zmq_setsockopt (client, ZMQ_IDENTITY, identity, strlen (identity)); zmq_connect (client, "tcp://localhost:5570"); zmq_pollitem_t items [] = { { client, 0, ZMQ_POLLIN, 0 } }; int request_nbr = 0; while (1) { // Tick once per second, pulling in arriving messages int centitick; for (centitick = 0; centitick < 100; centitick++) { zmq_poll (items, 1, 10000); if (items [0].revents & ZMQ_POLLIN) { zmsg_t *zmsg = zmsg_recv (client); printf ("%s: %s\n", identity, zmsg_body (zmsg)); zmsg_destroy (&zmsg); } } zmsg_t *zmsg = zmsg_new (); zmsg_body_fmt (zmsg, "request #%d", ++request_nbr); zmsg_send (&zmsg, client); } // Clean up and end task properly zmq_close (client); zmq_term (context); return (NULL); }
// Worker using REQ socket to do LRU routing // static void * worker_thread (void *context) { void *worker = zmq_socket (context, ZMQ_REQ); s_set_id (worker); // Makes tracing easier zmq_connect (worker, "ipc://backend.ipc"); // Tell broker we're ready for work s_send (worker, "READY"); while (1) { zmsg_t *zmsg = zmsg_recv (worker); printf ("Worker: %s\n", zmsg_body (zmsg)); zmsg_body_set (zmsg, "OK"); zmsg_send (&zmsg, worker); } return (NULL); }
int main (int argc, char *argv []) { int verbose = (argc > 1 && streq (argv [1], "-v")); mdcli_t *session = mdcli_new ("tcp://localhost:5555", verbose); // 1. Send 'echo' request to Titanic zmsg_t *request = zmsg_new ("Hello world"); zmsg_push (request, "echo"); zmsg_t *reply = s_service_call ( session, "titanic.request", &request); char *uuid = NULL; if (reply) { uuid = zmsg_pop (reply); zmsg_destroy (&reply); printf ("I: request UUID: %s\n", uuid); } // 2. Wait until we get a reply while (!s_interrupted) { s_sleep (100); request = zmsg_new (uuid); zmsg_t *reply = s_service_call ( session, "titanic.reply", &request); if (reply) { printf ("Reply: %s\n", zmsg_body (reply)); zmsg_destroy (&reply); // 3. Close request request = zmsg_new (uuid); reply = s_service_call (session, "titanic.close", &request); zmsg_destroy (&reply); break; } else { printf ("I: no reply yet, trying again...\n"); s_sleep (5000); // Try again in 5 seconds } } mdcli_destroy (&session); return 0; }
int main (void) { srandom ((unsigned) time (NULL)); void *context = zmq_init (1); void *worker = zmq_socket (context, ZMQ_REQ); // Set random identity to make tracing easier char identity [10]; sprintf (identity, "%04X-%04X", randof (0x10000), randof (0x10000)); zmq_setsockopt (worker, ZMQ_IDENTITY, identity, strlen (identity)); zmq_connect (worker, "tcp://localhost:5556"); // Tell queue we're ready for work printf ("I: (%s) worker ready\n", identity); s_send (worker, "READY"); int cycles = 0; while (1) { zmsg_t *zmsg = zmsg_recv (worker); // Simulate various problems, after a few cycles cycles++; if (cycles > 3 && randof (5) == 0) { printf ("I: (%s) simulating a crash\n", identity); zmsg_destroy (&zmsg); break; } else if (cycles > 3 && randof (5) == 0) { printf ("I: (%s) simulating CPU overload\n", identity); sleep (5); } printf ("I: (%s) normal reply - %s\n", identity, zmsg_body (zmsg)); sleep (1); // Do some heavy work zmsg_send (&zmsg, worker); } zmq_close (worker); zmq_term (context); return 0; }
static void s_service_internal (broker_t *self, char *service_name, zmsg_t *msg) { if (streq (service_name, "mmi.service")) { service_t *service = (service_t *) zhash_lookup (self->services, zmsg_body (msg)); if (service && service->workers) zmsg_body_set (msg, "200"); else zmsg_body_set (msg, "404"); } else zmsg_body_set (msg, "501"); // Remove & save client return envelope and insert the // protocol header and service name, then rewrap envelope. char *client = zmsg_unwrap (msg); zmsg_wrap (msg, MDPC_CLIENT, service_name); zmsg_wrap (msg, client, ""); free (client); zmsg_send (&msg, self->socket); }
int main (void) { s_version_assert (2, 1); srandom ((unsigned) time (NULL)); void *context = zmq_init (1); void *worker = s_worker_socket (context); // If liveness hits zero, queue is considered disconnected size_t liveness = HEARTBEAT_LIVENESS; size_t interval = INTERVAL_INIT; // Send out heartbeats at regular intervals uint64_t heartbeat_at = s_clock () + HEARTBEAT_INTERVAL; int cycles = 0; while (1) { zmq_pollitem_t items [] = { { worker, 0, ZMQ_POLLIN, 0 } }; zmq_poll (items, 1, HEARTBEAT_INTERVAL * 1000); if (items [0].revents & ZMQ_POLLIN) { // Get message // - 3-part envelope + content -> request // - 1-part "HEARTBEAT" -> heartbeat zmsg_t *msg = zmsg_recv (worker); if (msg_parts (msg) == 3) { // Simulate various problems, after a few cycles cycles++; if (cycles > 3 && randof (5) == 0) { printf ("I: (%s) simulating a crash\n", identity); zmsg_destroy (&msg); break; } else if (cycles > 3 && randof (5) == 0) { printf ("I: (%s) simulating CPU overload\n", identity); sleep (5); } printf ("I: (%s) normal reply - %s\n", identity, zmsg_body (msg)); zmsg_send (&msg, worker); liveness = HEARTBEAT_LIVENESS; sleep (1); // Do some heavy work } else if (msg_parts (msg) == 1 && strcmp (msg_body (msg), "HEARTBEAT") == 0) liveness = HEARTBEAT_LIVENESS; else { printf ("E: (%s) invalid message\n", identity); zmsg_dump (msg); } interval = INTERVAL_INIT; } else if (--liveness == 0) { printf ("W: (%s) heartbeat failure, can't reach queue\n", identity); printf ("W: (%s) reconnecting in %zd msec...\n", identity, interval); s_sleep (interval); if (interval < INTERVAL_MAX) interval *= 2; zmq_close (worker); worker = s_worker_socket (context); liveness = HEARTBEAT_LIVENESS; } // Send heartbeat to queue if it's time if (s_clock () > heartbeat_at) { heartbeat_at = s_clock () + HEARTBEAT_INTERVAL; printf ("I: (%s) worker heartbeat\n", identity); s_send (worker, "HEARTBEAT"); } } zmq_close (worker); zmq_term (context); return 0; }
int main (int argc, char *argv []) { // First argument is this broker's name // Other arguments are our peers' names // if (argc < 2) { printf ("syntax: peering1 me {you}...\n"); exit (EXIT_FAILURE); } char *self = argv [1]; printf ("I: preparing broker at %s...\n", self); srandom ((unsigned) time (NULL)); // Prepare our context and sockets void *context = zmq_init (1); char endpoint [256]; // Bind statebe to endpoint void *statebe = zmq_socket (context, ZMQ_PUB); snprintf (endpoint, 255, "ipc://%s-state.ipc", self); int rc = zmq_bind (statebe, endpoint); assert (rc == 0); // Connect statefe to all peers void *statefe = zmq_socket (context, ZMQ_SUB); zmq_setsockopt (statefe, ZMQ_SUBSCRIBE, "", 0); int argn; for (argn = 2; argn < argc; argn++) { char *peer = argv [argn]; printf ("I: connecting to state backend at '%s'\n", peer); snprintf (endpoint, 255, "ipc://%s-state.ipc", peer); rc = zmq_connect (statefe, endpoint); assert (rc == 0); } // Send out status messages to peers, and collect from peers // The zmq_poll timeout defines our own heartbeating // while (1) { // Initialize poll set zmq_pollitem_t items [] = { { statefe, 0, ZMQ_POLLIN, 0 } }; // Poll for activity, or 1 second timeout rc = zmq_poll (items, 1, 1000000); assert (rc >= 0); // Handle incoming status message if (items [0].revents & ZMQ_POLLIN) { zmsg_t *zmsg = zmsg_recv (statefe); printf ("%s - %s workers free\n", zmsg_address (zmsg), zmsg_body (zmsg)); zmsg_destroy (&zmsg); } else { // Send random value for worker availability zmsg_t *zmsg = zmsg_new (); zmsg_body_fmt (zmsg, "%d", randof (10)); // We stick our own address onto the envelope zmsg_wrap (zmsg, self, NULL); zmsg_send (&zmsg, statebe); } } // We never get here but clean up anyhow zmq_close (statefe); zmq_term (context); return EXIT_SUCCESS; }