zyre_event(3)
=============

NAME
----
zyre_event - no title found

SYNOPSIS
--------
----
//  This is a stable class, and may not change except for emergencies. It
//  is provided in stable builds.
//  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).                                            
ZYRE_EXPORT zyre_event_t *
    zyre_event_new (zyre_t *node);

//  Destructor; destroys an event instance
ZYRE_EXPORT void
    zyre_event_destroy (zyre_event_t **self_p);

//  Returns event type, as printable uppercase string. Choices are:   
//  "ENTER", "EXIT", "JOIN", "LEAVE", "EVASIVE", "WHISPER" and "SHOUT"
//  and for the local node: "STOP"                                    
ZYRE_EXPORT const char *
    zyre_event_type (zyre_event_t *self);

//  Return the sending peer's uuid as a string
ZYRE_EXPORT const char *
    zyre_event_peer_uuid (zyre_event_t *self);

//  Return the sending peer's public name as a string
ZYRE_EXPORT const char *
    zyre_event_peer_name (zyre_event_t *self);

//  Return the sending peer's ipaddress as a string
ZYRE_EXPORT const char *
    zyre_event_peer_addr (zyre_event_t *self);

//  Returns the event headers, or NULL if there are none
ZYRE_EXPORT zhash_t *
    zyre_event_headers (zyre_event_t *self);

//  Returns value of a header from the message headers   
//  obtained by ENTER. Return NULL if no value was found.
ZYRE_EXPORT const char *
    zyre_event_header (zyre_event_t *self, const char *name);

//  Returns the group name that a SHOUT event was sent to
ZYRE_EXPORT const char *
    zyre_event_group (zyre_event_t *self);

//  Returns the incoming message payload; the caller can modify the
//  message but does not own it and should not destroy it.         
ZYRE_EXPORT zmsg_t *
    zyre_event_msg (zyre_event_t *self);

//  Returns the incoming message payload, and pass ownership to the   
//  caller. The caller must destroy the message when finished with it.
//  After called on the given event, further calls will return NULL.  
//  Caller owns return value and must destroy it when done.
ZYRE_EXPORT zmsg_t *
    zyre_event_get_msg (zyre_event_t *self);

//  Print event to zsys log
ZYRE_EXPORT void
    zyre_event_print (zyre_event_t *self);

//  Self test of this class.
ZYRE_EXPORT void
    zyre_event_test (bool verbose);

----

DESCRIPTION
-----------

This class provides a higher-level API to the zyre_recv call, by doing
work that you will want to do in many cases, such as unpacking the peer
headers for each ENTER event received.

Please add @discuss section in ../src/zyre_event.c.

EXAMPLE
-------
.From zyre_event_test method
----
//  Create two nodes
zyre_t *node1 = zyre_new ("node1");
assert (node1);
zyre_set_header (node1, "X-HELLO", "World");
// use gossiping instead of beaconing, suits Travis better
zyre_gossip_bind (node1, "inproc://gossip-hub");
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);
// use gossiping instead of beaconing, suits Travis better
zyre_gossip_connect (node2, "inproc://gossip-hub");
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 (streq (zyre_event_type (event), "ENTER"));
const char *sender = zyre_event_peer_uuid (event);
assert (sender);
const char *name = zyre_event_peer_name (event);
assert (name);
assert (streq (name, "node1"));
const char *address = zyre_event_peer_addr (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 (streq (zyre_event_type (event), "JOIN")) {
    //  Parse SHOUT
    zyre_event_destroy (&event);
    event = zyre_event_new (node2);
    if (streq (zyre_event_type (event), "SHOUT")) {
        assert (streq (zyre_event_group (event), "GLOBAL"));
        zmsg_t *msg = zyre_event_get_msg (event);
        char *string = zmsg_popstr (msg);
        zmsg_destroy (&msg);
        assert (streq (string, "Hello, World"));
        free (string);
    }
    zyre_event_destroy (&event);
}
zyre_destroy (&node1);
zyre_destroy (&node2);
----
