static zre_peer_t * s_require_peer (agent_t *self, char *identity, char *address, uint16_t port) { zre_peer_t *peer = (zre_peer_t *) zhash_lookup (self->peers, identity); if (!peer) { // Purge any previous peer on same endpoint char endpoint [100]; snprintf (endpoint, 100, "%s:%hu", address, port); zhash_foreach (self->peers, agent_peer_purge, endpoint); peer = zre_peer_new (identity, self->peers, self->ctx); zre_peer_connect (peer, self->identity, endpoint); // Handshake discovery by sending HELLO as first message zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO); zre_msg_ipaddress_set (msg, zre_udp_host (self->udp)); zre_msg_mailbox_set (msg, self->port); zre_msg_groups_set (msg, zhash_keys (self->own_groups)); zre_msg_status_set (msg, self->status); zre_msg_headers_set (msg, zhash_dup (self->headers)); zre_peer_send (peer, &msg); zre_log_info (self->log, ZRE_LOG_MSG_EVENT_ENTER, zre_peer_endpoint (peer), endpoint); // Now tell the caller about the peer zstr_sendm (self->pipe, "ENTER"); zstr_send (self->pipe, identity); } return peer; }
int zre_msg_send_leave ( void *output, uint16_t sequence, char *group, byte status) { zre_msg_t *self = zre_msg_new (ZRE_MSG_LEAVE); zre_msg_sequence_set (self, sequence); zre_msg_group_set (self, group); zre_msg_status_set (self, status); return zre_msg_send (&self, output); }
int zre_msg_send_hello ( void *output, uint16_t sequence, char *ipaddress, uint16_t mailbox, zlist_t *groups, byte status, zhash_t *headers) { zre_msg_t *self = zre_msg_new (ZRE_MSG_HELLO); zre_msg_sequence_set (self, sequence); zre_msg_ipaddress_set (self, ipaddress); zre_msg_mailbox_set (self, mailbox); zre_msg_groups_set (self, zlist_dup (groups)); zre_msg_status_set (self, status); zre_msg_headers_set (self, zhash_dup (headers)); return zre_msg_send (&self, output); }
static int agent_recv_from_api (agent_t *self) { // Get the whole message off the pipe in one go zmsg_t *request = zmsg_recv (self->pipe); char *command = zmsg_popstr (request); if (!command) return -1; // Interrupted if (streq (command, "WHISPER")) { // Get peer to send message to char *identity = zmsg_popstr (request); zre_peer_t *peer = (zre_peer_t *) zhash_lookup (self->peers, identity); // Send frame on out to peer's mailbox, drop message // if peer doesn't exist (may have been destroyed) if (peer) { zre_msg_t *msg = zre_msg_new (ZRE_MSG_WHISPER); zre_msg_content_set (msg, zmsg_pop (request)); zre_peer_send (peer, &msg); } free (identity); } else if (streq (command, "SHOUT")) { // Get group to send message to char *name = zmsg_popstr (request); zre_group_t *group = (zre_group_t *) zhash_lookup (self->peer_groups, name); if (group) { zre_msg_t *msg = zre_msg_new (ZRE_MSG_SHOUT); zre_msg_group_set (msg, name); zre_msg_content_set (msg, zmsg_pop (request)); zre_group_send (group, &msg); } free (name); } else if (streq (command, "JOIN")) { char *name = zmsg_popstr (request); zre_group_t *group = (zre_group_t *) zhash_lookup (self->own_groups, name); if (!group) { // Only send if we're not already in group group = zre_group_new (name, self->own_groups); zre_msg_t *msg = zre_msg_new (ZRE_MSG_JOIN); zre_msg_group_set (msg, name); // Update status before sending command zre_msg_status_set (msg, ++(self->status)); zhash_foreach (self->peers, s_peer_send, msg); zre_msg_destroy (&msg); zre_log_info (self->log, ZRE_LOG_MSG_EVENT_JOIN, NULL, name); } free (name); } else if (streq (command, "LEAVE")) { char *name = zmsg_popstr (request); zre_group_t *group = (zre_group_t *) zhash_lookup (self->own_groups, name); if (group) { // Only send if we are actually in group zre_msg_t *msg = zre_msg_new (ZRE_MSG_LEAVE); zre_msg_group_set (msg, name); // Update status before sending command zre_msg_status_set (msg, ++(self->status)); zhash_foreach (self->peers, s_peer_send, msg); zre_msg_destroy (&msg); zhash_delete (self->own_groups, name); zre_log_info (self->log, ZRE_LOG_MSG_EVENT_LEAVE, NULL, name); } free (name); } else if (streq (command, "SET")) { char *name = zmsg_popstr (request); char *value = zmsg_popstr (request); zhash_update (self->headers, name, value); free (name); free (value); } else if (streq (command, "PUBLISH")) { char *logical = zmsg_popstr (request); char *physical = zmsg_popstr (request); // Virtual filename must start with slash assert (logical [0] == '/'); // We create symbolic link pointing to real file char *symlink = malloc (strlen (logical) + 3); sprintf (symlink, "%s.ln", logical + 1); fmq_file_t *file = fmq_file_new (self->fmq_outbox, symlink); int rc = fmq_file_output (file); assert (rc == 0); fprintf (fmq_file_handle (file), "%s\n", physical); fmq_file_destroy (&file); free (symlink); free (logical); free (physical); } else if (streq (command, "RETRACT")) { char *logical = zmsg_popstr (request); // Logical filename must start with slash assert (logical [0] == '/'); // We create symbolic link pointing to real file char *symlink = malloc (strlen (logical) + 3); sprintf (symlink, "%s.ln", logical + 1); fmq_file_t *file = fmq_file_new (self->fmq_outbox, symlink); fmq_file_remove (file); free (symlink); free (logical); } free (command); zmsg_destroy (&request); return 0; }
int zre_msg_test (bool verbose) { printf (" * zre_msg: "); // Simple create/destroy test zre_msg_t *self = zre_msg_new (0); assert (self); zre_msg_destroy (&self); // Create pair of sockets we can send through zctx_t *ctx = zctx_new (); assert (ctx); void *output = zsocket_new (ctx, ZMQ_DEALER); assert (output); zsocket_bind (output, "inproc://selftest"); void *input = zsocket_new (ctx, ZMQ_ROUTER); assert (input); zsocket_connect (input, "inproc://selftest"); // Encode/send/decode and verify each message type self = zre_msg_new (ZRE_MSG_HELLO); zre_msg_sequence_set (self, 123); zre_msg_ipaddress_set (self, "Life is short but Now lasts for ever"); zre_msg_mailbox_set (self, 123); zre_msg_groups_append (self, "Name: %s", "Brutus"); zre_msg_groups_append (self, "Age: %d", 43); zre_msg_status_set (self, 123); zre_msg_headers_insert (self, "Name", "Brutus"); zre_msg_headers_insert (self, "Age", "%d", 43); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_ipaddress (self), "Life is short but Now lasts for ever")); assert (zre_msg_mailbox (self) == 123); assert (zre_msg_groups_size (self) == 2); assert (streq (zre_msg_groups_first (self), "Name: Brutus")); assert (streq (zre_msg_groups_next (self), "Age: 43")); assert (zre_msg_status (self) == 123); assert (zre_msg_headers_size (self) == 2); assert (streq (zre_msg_headers_string (self, "Name", "?"), "Brutus")); assert (zre_msg_headers_number (self, "Age", 0) == 43); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_WHISPER); zre_msg_sequence_set (self, 123); zre_msg_content_set (self, zframe_new ("Captcha Diem", 12)); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (zframe_streq (zre_msg_content (self), "Captcha Diem")); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_SHOUT); zre_msg_sequence_set (self, 123); zre_msg_group_set (self, "Life is short but Now lasts for ever"); zre_msg_content_set (self, zframe_new ("Captcha Diem", 12)); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zframe_streq (zre_msg_content (self), "Captcha Diem")); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_JOIN); zre_msg_sequence_set (self, 123); zre_msg_group_set (self, "Life is short but Now lasts for ever"); zre_msg_status_set (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zre_msg_status (self) == 123); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_LEAVE); zre_msg_sequence_set (self, 123); zre_msg_group_set (self, "Life is short but Now lasts for ever"); zre_msg_status_set (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zre_msg_status (self) == 123); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_PING); zre_msg_sequence_set (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_PING_OK); zre_msg_sequence_set (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); zre_msg_destroy (&self); zctx_destroy (&ctx); printf ("OK\n"); return 0; }