/// // Constructor: receive an event from the zyre node, wraps zyre_recv. // The event may be a control message (ENTER, EXIT, JOIN, LEAVE) or // data (WHISPER, SHOUT). QZyreEvent::QZyreEvent (QZyre *node, QObject *qObjParent) : QObject (qObjParent) { this->self = zyre_event_new (node->self); }
void zyre_event_test (bool verbose) { printf (" * zyre_event: "); // @selftest // Create two nodes zyre_t *node1 = zyre_new ("node1"); assert (node1); zyre_set_header (node1, "X-HELLO", "World"); if (verbose) zyre_set_verbose (node1); if (zyre_start (node1)) { zyre_destroy (&node1); printf ("OK (skipping test, no UDP discovery)\n"); return; } zyre_join (node1, "GLOBAL"); zyre_t *node2 = zyre_new ("node2"); assert (node2); if (verbose) zyre_set_verbose (node2); int rc = zyre_start (node2); assert (rc == 0); zyre_join (node2, "GLOBAL"); // Give time for them to interconnect zclock_sleep (250); // One node shouts to GLOBAL zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "Hello, World"); zyre_shout (node1, "GLOBAL", &msg); zclock_sleep (100); // Parse ENTER zyre_event_t *event = zyre_event_new (node2); assert (zyre_event_type (event) == ZYRE_EVENT_ENTER); const char *sender = zyre_event_sender (event); assert (sender); const char *name = zyre_event_name (event); assert (name); assert (streq (name, "node1")); const char *address = zyre_event_address (event); assert (address); const char *header = zyre_event_header (event, "X-HELLO"); assert (header); zyre_event_destroy (&event); // Parse JOIN // We tolerate other events, which we can get if there are instances // of Zyre running somewhere on the network. event = zyre_event_new (node2); if (zyre_event_type (event) == ZYRE_EVENT_JOIN) { // Parse SHOUT zyre_event_destroy (&event); event = zyre_event_new (node2); if (zyre_event_type (event) == ZYRE_EVENT_SHOUT) { assert (streq (zyre_event_group (event), "GLOBAL")); msg = zyre_event_msg (event); char *string = zmsg_popstr (msg); assert (streq (string, "Hello, World")); free (string); } zyre_event_destroy (&event); } zyre_destroy (&node1); zyre_destroy (&node2); // @end printf ("OK\n"); }
int main (int argc, char *argv []) { puts (PRODUCT); puts (COPYRIGHT); puts (NOWARRANTY); int argn = 1; bool verbose = false; if (argn < argc && streq (argv [argn], "-h")) { puts ("syntax: hydrad [ directory ]"); puts (" -- defaults to .hydra in current directory"); exit (0); } if (argn < argc && streq (argv [argn], "-v")) { verbose = true; argn++; } // By default, current node runs in .hydra directory; create this if // it's missing (don't create directory passed as argument); char *workdir = ".hydra"; if (argn < argc) workdir = argv [argn++]; else zsys_dir_create (workdir); // ---------------------------------------------------------------------- // This code eventually goes into a reusable hydra actor class // Switch to working directory zsys_info ("hydrad: data store in %s directory", workdir); if (zsys_dir_change (workdir)) { zsys_error ("hydrad: cannot access %s: %s", workdir, strerror (errno)); return 1; } // Check we are the only process currently running here if (zsys_run_as ("hydrad.lock", NULL, NULL)) { zsys_error ("hydrad: cannot start process safely, exiting"); return 1; } // Get node identity from config file, or generate new identity zconfig_t *config = zconfig_load ("hydra.cfg"); if (!config) { // Set defaults for Hydra service config = zconfig_new ("root", NULL); zconfig_put (config, "/server/timeout", "5000"); zconfig_put (config, "/server/background", "0"); zconfig_put (config, "/server/verbose", "0"); } char *identity = zconfig_resolve (config, "/hydra/identity", NULL); if (!identity) { zuuid_t *uuid = zuuid_new (); zconfig_put (config, "/hydra/identity", zuuid_str (uuid)); zconfig_put (config, "/hydra/nickname", "Anonymous"); zconfig_save (config, "hydra.cfg"); zuuid_destroy (&uuid); } // Create store structure, if necessary zsys_dir_create ("content"); zsys_dir_create ("posts"); // Start server and bind to ephemeral TCP port. We can run many // servers on the same box, for testing. zactor_t *server = zactor_new (hydra_server, NULL); if (verbose) zstr_send (server, "VERBOSE"); // Bind Hydra service to ephemeral port and get that port number char *command; int port_nbr; zsock_send (server, "ss", "CONFIGURE", "hydra.cfg"); zsock_send (server, "ss", "BIND", "tcp://*:*"); zsock_send (server, "s", "PORT"); zsock_recv (server, "si", &command, &port_nbr); zsys_info ("hydrad: TCP server started on port=%d", port_nbr); assert (streq (command, "PORT")); free (command); // We're going to use Zyre for discovery and presence, and our own // Hydra protocol for content exchange zyre_t *zyre = zyre_new (NULL); if (verbose) zyre_set_verbose (zyre); char *hostname = zsys_hostname (); char *endpoint = zsys_sprintf ("tcp://%s:%d", hostname, port_nbr); zyre_set_header (zyre, "X-HYDRA", "%s", endpoint); zstr_free (&endpoint); zstr_free (&hostname); if (zyre_start (zyre)) { zsys_info ("hydrad: can't start Zyre discovery service"); zactor_destroy (&server); zyre_destroy (&zyre); return 1; } // When we get a new peer, handle it zpoller_t *poller = zpoller_new (zyre_socket (zyre), NULL); while (!zpoller_terminated (poller)) { void *which = zpoller_wait (poller, -1); if (which == zyre_socket (zyre)) { zyre_event_t *event = zyre_event_new (zyre); if (zyre_event_type (event) == ZYRE_EVENT_ENTER) { zsys_debug ("hydrad: new peer name=%s endpoint=%s", zyre_event_name (event), zyre_event_header (event, "X-HYDRA")); s_handle_peer (zyre_event_header (event, "X-HYDRA"), verbose); } zyre_event_destroy (&event); } else break; } zsys_info ("hydrad: shutting down..."); zpoller_destroy (&poller); // Shutdown all services zactor_destroy (&server); zyre_destroy (&zyre); zconfig_destroy (&config); return 0; }
/// // Constructor: receive an event from the zyre node, wraps zyre_recv. // The event may be a control message (ENTER, EXIT, JOIN, LEAVE) or // data (WHISPER, SHOUT). QmlZyreEvent *QmlZyreEventAttached::construct (QmlZyre *self) { QmlZyreEvent *qmlSelf = new QmlZyreEvent (); qmlSelf->self = zyre_event_new (self->self); return qmlSelf; };
event_t event() const { return event_t(zyre_event_new(m_self)); }
void ztask_monitor_api_loop (ztask_monitor_api_t *self) { zyre_t *node = zyre_new(); zyre_set_header(node, "X-ZTASK-MON", "TASK MON"); zyre_start(node); zyre_dump(node); if (self->pub_port >= 0) zclock_log("Publisher is listening on port %d ...", self->pub_port); zpoller_t *poller = zpoller_new (zyre_socket (node), NULL); uint64_t reap_at = zclock_time () + self->pub_timeout; zyre_event_t *event; while (!zsys_interrupted) { void *which = zpoller_wait (poller, self->pub_timeout); if (zpoller_terminated (poller)) { break; } if (which == zyre_socket (node)) { event = zyre_event_new(node); if (!event) break; if (zyre_event_type(event) == ZYRE_EVENT_ENTER) { } else if (zyre_event_type(event) == ZYRE_EVENT_EXIT) { char *data = (char *) zhash_lookup(self->nodes, (const char *) zyre_event_sender(event)); if (data) { zhash_delete(self->nodes, (const char *) zyre_event_sender(event)); free(data); } } else if (zyre_event_type(event) == ZYRE_EVENT_WHISPER) { zmsg_t *msg = zyre_event_msg(event); char *cpu_str = zmsg_popstr(msg); char *mem_rss_str = zmsg_popstr(msg); if (self->pub_sock) { char *data = (char *) zhash_lookup(self->nodes, (const char *) zyre_event_sender(event)); if (data) { zhash_delete(self->nodes, (const char *) zyre_event_sender(event)); free(data); } if (asprintf(&data, "{\"id\":\"%s\",%s,%s}", zyre_event_sender(event), cpu_str, mem_rss_str) < 0) data = NULL; zhash_insert(self->nodes, (const char *) zyre_event_sender(event), data); } else { zclock_log("From %s", zyre_event_sender(event)); zclock_log(" %s", cpu_str); zclock_log(" %s", mem_rss_str); } free(cpu_str); free(mem_rss_str); } zyre_event_destroy(&event); } if (zclock_time() >= reap_at) { reap_at = zclock_time() + self->pub_timeout; if (self->pub_sock) { char *data = ztask_monitor_api_json (self); if (data) { zmsg_t *msg = zmsg_new(); zmsg_addstr(msg, data); zclock_log("Sending %s ...", data); zmsg_send(&msg, self->pub_sock); free(data); } } } } zyre_stop(node); zpoller_destroy (&poller); zyre_destroy(&node); // Cleanup of self->nodes // char *wk = (char *) zhash_first (self->nodes); // while (wk) { // zhash_delete (self->nodes, wk); //// free (data); // wk = (char *) zhash_first (self->nodes); // } }
void ztask_run_manager_loop (ztask_run_manager_t *self) { assert (self); if (!self->packetizer) { zclock_log ("E: No packetizer set !!!"); return; } // Setting network interface if neede if (self->node_interface) zyre_set_interface(self->node, self->node_interface); zyre_set_header (self->node, "X-ZTASK-RUN", "ZTASK RUN"); zyre_start (self->node); zyre_dump (self->node); zclock_sleep (10); // ztask_packetizer_dump (self->packetizer); ztask_packet_t *packet; int request_sent = 0; zyre_event_t *event; while (!zsys_interrupted) { if (ztask_packetizer_is_finished (self->packetizer)) break; event = zyre_event_new (self->node); if (!event) break; if (zyre_event_type (event) == ZYRE_EVENT_ENTER) { // Ignoring nodes which don't have service X-ZTASK-NODE defined if (zyre_event_header (event, "X-ZTASK-NODE")) { zhash_insert (self->nodes, zyre_event_sender (event),""); ztask_log_debug (self->log, "Adding node -> workers=%ld", zhash_size (self->nodes)); } else { // TODO disconnect worker (zyre peer) somehow } } else if (zyre_event_type (event) == ZYRE_EVENT_EXIT) { if (zhash_lookup (self->nodes, zyre_event_sender (event))) { ztask_log_debug (self->log, "Removing node -> workers=%ld", zhash_size (self->nodes)); zhash_delete (self->nodes, zyre_event_sender (event)); // Cleanup packetizer in case ztask_node was killed request_sent -= ztask_packetizer_running_node_cleanup (self->packetizer, zyre_event_sender (event)); } } else if (zyre_event_type (event) == ZYRE_EVENT_WHISPER) { // Ingoring whispers when they are not from our nodes if (!zhash_lookup(self->nodes, zyre_event_sender (event))) { ztask_log_warning (self->log, "W: Ingoring whisper from %s", zyre_event_sender (event)); zyre_event_destroy (&event); continue; } zmsg_t *msg_report = zyre_event_msg(event); char *str_msg = zmsg_popstr (msg_report); if (streq(str_msg, "REQUEST")) { // Let's handle request packet = ztask_packetizer_next_packet (self->packetizer); if (packet) { char *cmd; if ( asprintf (&cmd, "%s", ztask_packet_cmd (packet)) < 0) cmd = NULL; assert (cmd); zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "REQUEST"); zmsg_addstrf (msg, "%s_%ld", zyre_uuid (self->node), ztask_packet_id (packet)); zmsg_addstr (msg, cmd); zyre_whisper (self->node, zyre_event_sender (event), &msg); ztask_packet_set_node (packet, zyre_event_sender (event)); request_sent++; ztask_packetizer_info (self->packetizer, request_sent); ztask_log_debug (self->log, "ID=%s_%ld cmd='%s' running=%d", zyre_uuid (self->node), ztask_packet_id (packet), cmd, request_sent); free (cmd); } else { zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "NO_PACKETS"); zyre_whisper (self->node, zyre_event_sender (event), &msg); } } else if (streq(str_msg, "REPORT")) { // It's report char *str_id = zmsg_popstr (msg_report); char *str_pid_rc = zmsg_popstr (msg_report); ztask_log_debug (self->log, "REPORT ID=%s rc=%s", str_id, str_pid_rc); ztask_packetizer_report (self->packetizer, str_id, str_pid_rc); request_sent--; ztask_packetizer_info (self->packetizer, request_sent); free (str_id); free (str_pid_rc); } else { ztask_log_error (self->log, "E: ztask_run_manager_loop : Wrong message %s", str_msg); assert (false); } free (str_msg); } zyre_event_destroy (&event); } // FIXME : simplify zhash_foreach() zlist_t *keys = zhash_keys (self->nodes); char *key = (char *) zlist_first (keys); while (key) { zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "END"); zyre_whisper (self->node, key, &msg); key = (char *) zlist_next (keys); } zlist_destroy (&keys); // wait for shout to be delivered zclock_sleep (100); ztask_packetizer_summary(self->packetizer, 0); zyre_stop (self->node); }
int main (int argc, char *argv []) { int argn = 1; if (argn == argc || streq (argv [argn], "-h") || streq (argv [argn], "--help")) { puts ("midicast [-v] [-p port] [-i interface]"); puts ("Reads MIDI events from port and sends to Zyre MIDI group"); puts (" -h, --help: this help"); puts (" -v, --verbose: trace events as they happen"); puts (" -p, --port: specify port name, e.g. '-p hw:1,0,0'"); puts (" -i, --interface: specify WiFi interface, e.g. '-i wlan0'"); return 0; } char *midi_port_name = "hw:2,0"; char *wifi_interface = NULL; bool verbose = false; while (argn < argc) { if (streq (argv [argn], "-p") || streq (argv [argn], "--port")) midi_port_name = argv [++argn]; else if (streq (argv [argn], "-i") || streq (argv [argn], "--interface")) wifi_interface = argv [++argn]; else if (streq (argv [argn], "-v") || streq (argv [argn], "--verbose")) verbose = true; argn++; } snd_rawmidi_t *output; int rc = snd_rawmidi_open (NULL, &output, midi_port_name, SND_RAWMIDI_SYNC); if (rc < 0) { zsys_error ("cannot open port \"%s\": %s", midi_port_name, snd_strerror (rc)); return 0; } zsys_info ("forwarding MIDI cast to %s", midi_port_name); zyre_t *zyre = zyre_new (NULL); if (wifi_interface) zyre_set_interface (zyre, wifi_interface); zyre_start (zyre); zyre_join (zyre, "MIDI"); zsys_info ("this player is %s", zyre_name (zyre)); while (!zsys_interrupted) { zyre_event_t *event = zyre_event_new (zyre); if (!event) { printf (" interrupted\n"); break; } if (zyre_event_type (event) == ZYRE_EVENT_JOIN) zsys_info ("[%s] player joined", zyre_event_peer_name (event)); else if (zyre_event_type (event) == ZYRE_EVENT_LEAVE) zsys_info ("[%s] player left", zyre_event_peer_name (event)); else if (zyre_event_type (event) == ZYRE_EVENT_SHOUT) { if (streq (zyre_event_group (event), "MIDI")) { zframe_t *frame = zmsg_first (zyre_event_msg (event)); // Forward the MIDI event snd_rawmidi_write (output, zframe_data (frame), zframe_size (frame)); if (verbose) { printf ("%zd:", zframe_size (frame)); int byte_nbr; for (byte_nbr = 0; byte_nbr < zframe_size (frame); byte_nbr++) printf (" %02X", zframe_data (frame) [byte_nbr]); printf ("\n"); } } } zyre_event_destroy (&event); } snd_rawmidi_close (output); zyre_destroy (&zyre); return 0; }
bool GroupNodeImpl::spin_once() { // read a new event from the zyre node, interrupt if (zsys_interrupted || !ok() || stopped_) { BOOST_LOG_TRIVIAL(debug) << "GroupNode::spin_once(): zsysi " << (int)zsys_interrupted << " ok " << (int)!ok() << " stopped " << (int)stopped_ << std::endl; return false; } BOOST_LOG_TRIVIAL(debug) << "waiting for event" << std::endl; ScopedEvent e(zyre_event_new(node_)); // apparently, blocks until event occurs. // will be destroyed at the end of the function if (e.valid() && ok()) { BOOST_LOG_TRIVIAL(debug) << "got event" << std::endl; zyre_event_type_t t = e.type(); switch (t) { case ZYRE_EVENT_WHISPER: { std::string name = e.peer_name(); BOOST_LOG_TRIVIAL(debug) << name << " whispers -> " << node_name_ << std::endl; std::string peer_uuid = e.peer_uuid(); BOOST_LOG_TRIVIAL(debug) << " peer id " << peer_uuid << std::endl; zmsg_t* msg = e.message(); handle_whisper(peer_uuid, msg); } break; case ZYRE_EVENT_SHOUT: { std::string group_id = e.group(); BOOST_LOG_TRIVIAL(debug) << e.peer_name() << " " << group_id << " shouts ->" << node_name_ << std::endl; std::string peer_uuid = e.peer_uuid(); BOOST_LOG_TRIVIAL(debug) << " peer id " << peer_uuid << std::endl; zmsg_t* msg = e.message(); handle_shout(group_id, peer_uuid, msg); } break; case ZYRE_EVENT_ENTER: { std::string name = e.peer_name(); BOOST_LOG_TRIVIAL(debug) << name << " enters | " << node_name_ << std::endl; } break; case ZYRE_EVENT_JOIN: { std::string group_id = e.group(); BOOST_LOG_TRIVIAL(debug) << e.peer_name() << " joins " << group_id << " | " << node_name_ << std::endl; { basic_lock lk(join_mutex_); joins_[group_id]++; } join_cond_.notify_all(); } break; case ZYRE_EVENT_LEAVE: { std::string group_id = e.group(); BOOST_LOG_TRIVIAL(debug) << e.peer_name() << " leaves " << group_id << " | " << node_name_ << std::endl; { basic_lock lk(join_mutex_); joins_[group_id]--; }} break; case ZYRE_EVENT_EXIT: { if (e.peer_name() == node_name_) { stopped_ = true; } BOOST_LOG_TRIVIAL(debug) << e.peer_name() << " exits | " << node_name_ << std::endl; } break; case ZYRE_EVENT_STOP: { if (e.peer_name() == node_name_) { stopped_ = true; } BOOST_LOG_TRIVIAL(debug) << e.peer_name() << " stops | " << node_name_ << std::endl; } return false; default: BOOST_LOG_TRIVIAL(debug) << "got an unexpected event" << std::endl; } } else { BOOST_LOG_TRIVIAL(debug) << "No event" << std::endl; join_cond_.notify_all(); return false; } return true; }