示例#1
0
文件: zstr.c 项目: DeanHH/czmq
void
zstr_test (bool verbose)
{
    printf (" * zstr: ");

    //  @selftest
    //  Create two PAIR sockets and connect over inproc
    zsock_t *output = zsock_new_pair ("@inproc://zstr.test");
    assert (output);
    zsock_t *input = zsock_new_pair (">inproc://zstr.test");
    assert (input);

    //  Send ten strings, five strings with MORE flag and then END
    int string_nbr;
    for (string_nbr = 0; string_nbr < 10; string_nbr++)
        zstr_sendf (output, "this is string %d", string_nbr);
    zstr_sendx (output, "This", "is", "almost", "the", "very", "END", NULL);

    //  Read and count until we receive END
    string_nbr = 0;
    for (string_nbr = 0;; string_nbr++) {
        char *string = zstr_recv (input);
        if (streq (string, "END")) {
            zstr_free (&string);
            break;
        }
        zstr_free (&string);
    }
    assert (string_nbr == 15);

    zsock_destroy (&input);
    zsock_destroy (&output);
    //  @end

    printf ("OK\n");
}
示例#2
0
void *client_task (void *args)
{
    zctx_t *ctx = zctx_new ();
    void *subscriber = zsocket_new (ctx, ZMQ_SUB);
    void *pusher = zsocket_new (ctx, ZMQ_PUSH);
    zsocket_connect (subscriber, "tcp://localhost:5563");
    zsocket_connect (pusher, "tcp://localhost:5564");

    int i;
    for (i = 0; i < 1000000; i++) {
        zsocket_set_subscribe (subscriber, "A");

        zmq_pollitem_t polla [] = { { pusher, 0, ZMQ_POLLOUT, 0 } };
        if (zmq_poll (polla, 1, 100) == 1)
            zstr_send (pusher, "B");

        zmq_pollitem_t pollb [] = { { subscriber, 0, ZMQ_POLLIN, 0 } };
        if (zmq_poll (pollb, 1, 100) == 1)
            free (zstr_recv (subscriber));

        zsocket_set_unsubscribe (subscriber, "A");
    }
    return NULL;
}
示例#3
0
文件: zyre_node.c 项目: Muraad/zyre
static void
zyre_node_recv_beacon (zyre_node_t *self)
{
    //  Get IP address and beacon of peer
    char *ipaddress = zstr_recv (self->beacon);
    zframe_t *frame = zframe_recv (self->beacon);
    if (ipaddress == NULL)
        return;                 //  Interrupted

    //  Ignore anything that isn't a valid beacon
    beacon_t beacon = { { 0 } };
    if (zframe_size (frame) == sizeof (beacon_t))
        memcpy (&beacon, zframe_data (frame), zframe_size (frame));
    zframe_destroy (&frame);
    if (beacon.version != BEACON_VERSION)
        return;                 //  Garbage beacon, ignore it

    zuuid_t *uuid = zuuid_new ();
    zuuid_set (uuid, beacon.uuid);
    if (beacon.port) {
        char endpoint [30];
        sprintf (endpoint, "tcp://%s:%d", ipaddress, ntohs (beacon.port));
        zyre_peer_t *peer = zyre_node_require_peer (self, uuid, endpoint);
        zyre_peer_refresh (peer);
    }
    else {
        //  Zero port means peer is going away; remove it if
        //  we had any knowledge of it already
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (
            self->peers, zuuid_str (uuid));
        if (peer)
            zyre_node_remove_peer (self, peer);
    }
    zuuid_destroy (&uuid);
    zstr_free (&ipaddress);
}
示例#4
0
static int timer_main_serial_loop(zloop_t *loop, int timer_id, void *arg) {
    ticket_printer_t *self = (ticket_printer_t *) arg;
    if (self->serial_printer == NULL) {
        s_restart_boca_serial(self, self->boca_serial_port);
        return 0;
    }
    if (!s_heartbeat_boca_serial(self)) {
        enum BOCA_STATUS status = boca_serial_status(self->serial_printer);
        if (self->verbose && status != BOCA_UNKNOWN) {
            zsys_debug("ticket printer: got serial printer status %s.", boca_status_display(status));
        }
        s_handle_boca_status(self, &status, false);
    }
    switch (self->state) {
        case STATE_PRINTING:
            s_print_tix(self, true);
            break;
        case STATE_IDLE:
            s_print_tix(self, true);
            break;
        case STATE_ERROR:
            zstr_send(self->ticket_store_req, "TICKETUNPRINTED");
            char *code = zstr_recv(self->ticket_store_req);
            if (code != NULL && streq(code, "OK")) {
                self->tix_counter = 0;
            }
            if (code != NULL) zstr_free(&code);
            free(self->last_token);
            self->last_token = strdup("");
            s_restart_boca_serial(self, self->boca_serial_port);
            break;
        case STATE_PAUSE:
            break;
    }
    return 0;
}
示例#5
0
文件: zsocket.c 项目: azverkan/czmq
int
zsocket_test (Bool verbose)
{
    printf (" * zsocket: ");

    //  @selftest
    zctx_t *ctx = zctx_new ();

    //  Create a detached thread, let it run
    char *interf = "*";
    char *domain = "localhost";
    int service = 5560;

    void *writer = zsocket_new (ctx, ZMQ_PUSH);
    void *reader = zsocket_new (ctx, ZMQ_PULL);
    assert (streq (zsocket_type_str (writer), "PUSH"));
    assert (streq (zsocket_type_str (reader), "PULL"));
    int rc = zsocket_bind (writer, "tcp://%s:%d", interf, service);
    assert (rc == service);
    zsocket_connect (reader, "tcp://%s:%d", domain, service);
    zstr_send (writer, "HELLO");
    char *message = zstr_recv (reader);
    assert (message);
    assert (streq (message, "HELLO"));
    free (message);

    int port = zsocket_bind (writer, "tcp://%s:*", interf);
    assert (port >= ZSOCKET_DYNFROM && port <= ZSOCKET_DYNTO);

    zsocket_destroy (ctx, writer);
    zctx_destroy (&ctx);
    //  @end

    printf ("OK\n");
    return 0;
}
示例#6
0
文件: zmonitor.c 项目: TangCheng/czmq
static void
s_agent_task (void *args, zctx_t *ctx, void *pipe)
{
    char *endpoint = zstr_recv (pipe);
    assert (endpoint);

    agent_t *self = s_agent_new (ctx, pipe, endpoint);
    zpoller_t *poller = zpoller_new (self->pipe, self->socket, NULL);

    while (!self->terminated) {
        //  Poll on API pipe and on monitor socket
        void *result = zpoller_wait (poller, -1);
        if (result == NULL)
            break;              // Interrupted
        else
        if (result == self->pipe)
            s_api_command (self);
        else
        if (result == self->socket)
            s_socket_event (self);
    }
    zpoller_destroy (&poller);
    s_agent_destroy (&self);
}
示例#7
0
void
zproxy_v2_test (bool verbose)
{
    printf (" * zproxy (deprecated): ");
    if (verbose)
        printf ("\n");

    //  @selftest
    zctx_t *ctx = zctx_new ();
    assert (ctx);
    void *frontend = zsocket_new (ctx, ZMQ_PULL);
    assert (frontend);
    int rc = zsocket_bind (frontend, "inproc://frontend");
    assert (rc == 0);
    void *backend = zsocket_new (ctx, ZMQ_PUSH);
    assert (backend);
    rc = zsocket_bind (backend, "inproc://backend");
    assert (rc == 0);
    zproxy_t *proxy = zproxy_new (ctx, frontend, backend);
    assert (proxy);

    //  Connect application sockets to proxy
    void *faucet = zsocket_new (ctx, ZMQ_PUSH);
    assert (faucet);
    rc = zsocket_connect (faucet, "inproc://frontend");
    assert (rc == 0);
    void *sink = zsocket_new (ctx, ZMQ_PULL);
    assert (sink);
    rc = zsocket_connect (sink, "inproc://backend");
    assert (rc == 0);

    //  Send some messages and check they arrived
    zstr_send (faucet, "Hello");
    char *string = zstr_recv (sink);
    assert (streq (string, "Hello"));
    zstr_free (&string);
    
    //  Check pause/resume functionality
    zproxy_pause (proxy);
    zstr_send (faucet, "World");

    zproxy_resume (proxy);
    string = zstr_recv (sink);
    assert (streq (string, "World"));
    zstr_free (&string);
    
    //  Create capture socket, must be a PULL socket
    void *capture = zsocket_new (ctx, ZMQ_PULL);
    assert (capture);
    rc = zsocket_bind (capture, "inproc://capture");
    assert (rc == 0);

    //  Switch on capturing, check that it works
    zproxy_capture (proxy, "inproc://capture");
    zstr_send (faucet, "Hello");
    
    string = zstr_recv (sink);
    assert (streq (string, "Hello"));
    zstr_free (&string);
    
    string = zstr_recv (capture);
    assert (streq (string, "Hello"));
    zstr_free (&string);
    zproxy_destroy (&proxy);
    zctx_destroy (&ctx);

    //  @end
    printf ("OK\n");
}
示例#8
0
char *
curve_client_recvstr (curve_client_t *self)
{
    assert (self);
    return zstr_recv (self->data);
}
示例#9
0
文件: zyre_node.c 项目: opedroso/zyre
void
zyre_node_actor (zsock_t *pipe, void *args)
{
    //  Create node instance to pass around
    zyre_node_t *self = zyre_node_new (pipe, args);
    if (!self)                  //  Interrupted
        return;

    //  Signal actor successfully initialized
    zsock_signal (self->pipe, 0);

    //  Loop until the agent is terminated one way or another
    int64_t reap_at = zclock_mono () + REAP_INTERVAL;
    while (!self->terminated) {

        // Start beacon as soon as we can
        if (self->beacon && self->port <= 0) {
            //  Our hostname is provided by zbeacon
            zsock_send(self->beacon, "si", "CONFIGURE", self->beacon_port);
            char *hostname = zstr_recv(self->beacon);

            // Is UDP broadcast interface available?
            if (!streq(hostname, "")) {
                if (zsys_ipv6())
                    self->port = zsock_bind(self->inbox, "tcp://%s%%%s:*", zsys_ipv6_address(), zsys_interface());
                else
                    self->port = zsock_bind(self->inbox, "tcp://%s:*", hostname);

                if (self->port > 0) {
                    assert(!self->endpoint);   //  If caller set this, we'd be using gossip
                    if (streq(zsys_interface(), "*")) {
                        char *hostname = zsys_hostname();
                        self->endpoint = zsys_sprintf("tcp://%s:%d", hostname, self->port);
                        zstr_free(&hostname);
                    }
                    else {
                        self->endpoint = strdup(zsock_endpoint(self->inbox));
                    }

                    //  Set broadcast/listen beacon
                    beacon_t beacon;
                    beacon.protocol[0] = 'Z';
                    beacon.protocol[1] = 'R';
                    beacon.protocol[2] = 'E';
                    beacon.version = BEACON_VERSION;
                    beacon.port = htons(self->port);
                    zuuid_export(self->uuid, beacon.uuid);
                    zsock_send(self->beacon, "sbi", "PUBLISH",
                        (byte *)&beacon, sizeof(beacon_t), self->interval);
                    zsock_send(self->beacon, "sb", "SUBSCRIBE", (byte *) "ZRE", 3);
                    zpoller_add(self->poller, self->beacon);

                    //  Start polling on inbox
                    zpoller_add(self->poller, self->inbox);
                }
            }
            zstr_free(&hostname);
        }

        int timeout = (int) (reap_at - zclock_mono ());
        if (timeout > REAP_INTERVAL)
            timeout = REAP_INTERVAL;
        else
        if (timeout < 0)
            timeout = 0;

        zsock_t *which = (zsock_t *) zpoller_wait (self->poller, timeout);
        if (which == self->pipe)
            zyre_node_recv_api (self);
        else
        if (which == self->inbox)
            zyre_node_recv_peer (self);
        else
        if (self->beacon
        && (void *) which == self->beacon)
            zyre_node_recv_beacon (self);
        else
        if (self->gossip
        && (zactor_t *) which == self->gossip)
            zyre_node_recv_gossip (self);
        else
        if (zpoller_terminated (self->poller))
            break;          //  Interrupted, check before expired
        else
        if (zpoller_expired (self->poller)) {
            if (zclock_mono () >= reap_at) {
                void *item;
                reap_at = zclock_mono () + REAP_INTERVAL;
                //  Ping all peers and reap any expired ones
                for (item = zhash_first (self->peers); item != NULL;
                        item = zhash_next (self->peers))
                    zyre_node_ping_peer (zhash_cursor (self->peers), item, self);
            }
        }
    }
    zyre_node_destroy (&self);
}
示例#10
0
文件: zsocket.c 项目: aburan28/czmq
int
zsocket_test (bool verbose)
{
    printf (" * zsocket: ");

    //  @selftest
    zctx_t *ctx = zctx_new ();
    assert (ctx);

    //  Create a detached thread, let it run
    char *interf = "*";
    char *domain = "localhost";
    int service = 5560;

    void *writer = zsocket_new (ctx, ZMQ_PUSH);
    assert (writer);
    void *reader = zsocket_new (ctx, ZMQ_PULL);
    assert (reader);
    assert (streq (zsocket_type_str (writer), "PUSH"));
    assert (streq (zsocket_type_str (reader), "PULL"));
    int rc = zsocket_bind (writer, "tcp://%s:%d", interf, service);
    assert (rc == service);
    rc = zsocket_connect (reader, "tcp://%s:%d", domain, service);
    assert (rc == 0);
    zstr_send (writer, "HELLO");
    char *message = zstr_recv (reader);
    assert (message);
    assert (streq (message, "HELLO"));
    free (message);
    
    //  Test binding to ports
    int port = zsocket_bind (writer, "tcp://%s:*", interf);
    assert (port >= ZSOCKET_DYNFROM && port <= ZSOCKET_DYNTO);

    assert (zsocket_poll (writer, 100) == false);

    rc = zsocket_connect (reader, "txp://%s:%d", domain, service);
    assert (rc == -1);

    //  Test sending frames to socket
    rc = zsocket_sendmem (writer,"ABC", 3, ZFRAME_MORE);
    assert (rc == 0);
    rc = zsocket_sendmem (writer, "DEFG", 4, 0);
    assert (rc == 0);
    
    zframe_t *frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "ABC"));
    assert (zframe_more (frame));
    zframe_destroy (&frame);
    
    frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "DEFG"));
    assert (!zframe_more (frame));
    zframe_destroy (&frame);

    //  Test zframe_sendmem_zero_copy
    rc = zsocket_sendmem_zero_copy (writer, strdup ("ABC"), 3,
                                    s_test_free_str_cb, NULL, ZFRAME_MORE);
    assert (rc == 0);
    rc = zsocket_sendmem_zero_copy (writer, strdup ("DEFG"), 4,
                                    s_test_free_str_cb, NULL, 0);
    assert (rc == 0);
    
    frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "ABC"));
    assert (zframe_more (frame));
    zframe_destroy (&frame);
    
    frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "DEFG"));
    assert (!zframe_more (frame));
    zframe_destroy (&frame);

    zsocket_destroy (ctx, writer);
    zctx_destroy (&ctx);
    //  @end

    printf ("OK\n");
    return 0;
}
示例#11
0
void
zsocket_test (bool verbose)
{
    printf (" * zsocket (deprecated): ");

    //  @selftest
    zctx_t *ctx = zctx_new ();
    assert (ctx);

    //  Create a detached thread, let it run
    char *interf = "127.0.0.1";
    char *domain = "localhost";
    int service = 5560;

    void *writer = zsocket_new (ctx, ZMQ_PUSH);
    assert (writer);
    void *reader = zsocket_new (ctx, ZMQ_PULL);
    assert (reader);
    assert (streq (zsocket_type_str (writer), "PUSH"));
    assert (streq (zsocket_type_str (reader), "PULL"));
    int rc = zsocket_bind (writer, "tcp://%s:%d", interf, service);
    assert (rc == service);

#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (3, 2, 0))
    //  Check unbind
    rc = zsocket_unbind (writer, "tcp://%s:%d", interf, service);
    assert (rc == 0);

    //  In some cases and especially when running under Valgrind, doing
    //  a bind immediately after an unbind causes an EADDRINUSE error.
    //  Even a short sleep allows the OS to release the port for reuse.
    zclock_sleep (100);

    //  Bind again
    rc = zsocket_bind (writer, "tcp://%s:%d", interf, service);
    assert (rc == service);
#endif

    rc = zsocket_connect (reader, "tcp://%s:%d", domain, service);
    assert (rc == 0);
    zstr_send (writer, "HELLO");
    char *message = zstr_recv (reader);
    assert (message);
    assert (streq (message, "HELLO"));
    free (message);

    //  Test binding to ports
    int port = zsocket_bind (writer, "tcp://%s:*", interf);
    assert (port >= ZSOCKET_DYNFROM && port <= ZSOCKET_DYNTO);

    assert (zsocket_poll (writer, 100) == false);

    //  Test error state when connecting to an invalid socket type
    //  ('txp://' instead of 'tcp://', typo intentional)
    rc = zsocket_connect (reader, "txp://%s:%d", domain, service);
    assert (rc == -1);

    //  Test sending frames to socket
    rc = zsocket_sendmem (writer, "ABC", 3, ZFRAME_MORE);
    assert (rc == 0);
    rc = zsocket_sendmem (writer, "DEFG", 4, 0);
    assert (rc == 0);

    zframe_t *frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "ABC"));
    assert (zframe_more (frame));
    zframe_destroy (&frame);

    frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "DEFG"));
    assert (!zframe_more (frame));
    zframe_destroy (&frame);

    rc = zsocket_signal (writer);
    assert (rc == 0);
    rc = zsocket_wait (reader);
    assert (rc == 0);

    zsocket_destroy (ctx, reader);
    zsocket_destroy (ctx, writer);
    zctx_destroy (&ctx);
    //  @end

    printf ("OK\n");
}
示例#12
0
int main(int argc, char *argv[]) {
  printf("Organizer started.\n");
  zsock_t *executer_sock = zsock_new_req("tcp://127.0.0.1:98789");

  while (1) {
    char cmd[50] = {0};
    printf("What do you want? ");
    scanf("%s", &cmd);

    if (streq(cmd, "teleport")) {
      char target[50] = {0}, name[50] = {0};
      printf("Which? Where? ");
      scanf("%s %s", &name, &target);

      /*printf("Name: %s\tTarget: %s\n", name, target);*/
      OEMsg oem = OEMSG__INIT;
      Teleport tpm = TELEPORT__INIT;
      void *buf;
      unsigned len;

      tpm.vm_name = name;
      tpm.target_ip = target;
      oem.teleport = &tpm;
      oem.type = OEMSG__TYPE__TELEPORT;
      len = oemsg__get_packed_size(&oem);

      buf = malloc(len);
      oemsg__pack(&oem, buf);

      /*printf(buf);*/

      zframe_t *frame = zframe_new(buf, len);
      zframe_send(&frame, executer_sock, 0);
      /*zstr_send(executer_sock, buf);*/
      memset(buf, 0, len * (sizeof buf[0]));
      free(buf);

      char *smsg;
      smsg = zstr_recv(executer_sock);
      free(smsg);
    } else if (streq(cmd, "start")) {
      char name[50] = {0};
      printf("Which? ");
      scanf("%s", &name);

      OEMsg oem = OEMSG__INIT;
      Start sm = START__INIT;
      void *buf;
      unsigned len;

      sm.vm_name = name;
      oem.start = &sm;
      oem.type = OEMSG__TYPE__START;
      len = oemsg__get_packed_size(&oem);

      buf = malloc(len);
      oemsg__pack(&oem, buf);

      /*printf(buf);*/

      zframe_t *frame = zframe_new(buf, len);
      zframe_send(&frame, executer_sock, 0);
      /*zstr_send(executer_sock, buf);*/
      memset(buf, 0, len * (sizeof buf[0]));
      free(buf);

      char *smsg;
      smsg = zstr_recv(executer_sock);
      free(smsg);

    } else if (streq(cmd, "exit")) {
      break;
    } else {
      break;
    }
  }

  zsock_destroy(&executer_sock);
  return 0;
}
示例#13
0
文件: zpoller.c 项目: evoskuil/czmq
void
zpoller_test (bool verbose)
{
    printf (" * zpoller: ");

    //  @selftest
    //  Create a few sockets
    zsock_t *vent = zsock_new (ZMQ_PUSH);
    assert (vent);
    int port_nbr = zsock_bind (vent, "tcp://127.0.0.1:*");
    assert (port_nbr != -1);
    zsock_t *sink = zsock_new (ZMQ_PULL);
    assert (sink);
    int rc = zsock_connect (sink, "tcp://127.0.0.1:%d", port_nbr);
    assert (rc != -1);
    zsock_t *bowl = zsock_new (ZMQ_PULL);
    assert (bowl);
    zsock_t *dish = zsock_new (ZMQ_PULL);
    assert (dish);

    //  Set up poller
    zpoller_t *poller = zpoller_new (bowl, dish, NULL);
    assert (poller);

    // Add a reader to the existing poller
    rc = zpoller_add (poller, sink);
    assert (rc == 0);

    zstr_send (vent, "Hello, World");

    //  We expect a message only on the sink
    zsock_t *which = (zsock_t *) zpoller_wait (poller, -1);
    assert (which == sink);
    assert (zpoller_expired (poller) == false);
    assert (zpoller_terminated (poller) == false);
    char *message = zstr_recv (which);
    assert (streq (message, "Hello, World"));
    zstr_free (&message);

    //  Stop polling reader
    rc = zpoller_remove (poller, sink);
    assert (rc == 0);

    // Removing a non-existent reader shall fail
    rc = zpoller_remove (poller, sink);
    assert (rc == -1);
    assert (errno == EINVAL);

    //  Check we can poll an FD
    rc = zsock_connect (bowl, "tcp://127.0.0.1:%d", port_nbr);
    assert (rc != -1);
    SOCKET fd = zsock_fd (bowl);
    rc = zpoller_add (poller, (void *) &fd);
    assert (rc != -1);
    zstr_send (vent, "Hello again, world");
    assert (zpoller_wait (poller, 500) == &fd);

    // Check zpoller_set_nonstop ()
    zsys_interrupted = 1;
    zpoller_wait (poller, 0);
    assert (zpoller_terminated (poller));
    zpoller_set_nonstop (poller, true);
    zpoller_wait (poller, 0);
    assert (!zpoller_terminated (poller));
    zsys_interrupted = 0;

    zpoller_destroy (&poller);
    zsock_destroy (&vent);
    zsock_destroy (&sink);
    zsock_destroy (&bowl);
    zsock_destroy (&dish);

#ifdef ZMQ_SERVER
    //  Check thread safe sockets
    zpoller_destroy (&poller);
    zsock_t *client = zsock_new (ZMQ_CLIENT);
    assert (client);
    zsock_t *server = zsock_new (ZMQ_SERVER);
    assert (server);
    poller = zpoller_new (client, server, NULL);
    assert (poller);
    port_nbr = zsock_bind (server, "tcp://127.0.0.1:*");
    assert (port_nbr != -1);
    rc = zsock_connect (client, "tcp://127.0.0.1:%d", port_nbr);
    assert (rc != -1);

    zstr_send (client, "Hello, World");

    //  We expect a message only on the server
    which = (zsock_t *) zpoller_wait (poller, -1);
    assert (which == server);
    assert (zpoller_expired (poller) == false);
    assert (zpoller_terminated (poller) == false);
    message = zstr_recv (which);
    assert (streq (message, "Hello, World"));
    zstr_free (&message);

    zpoller_destroy (&poller);
    zsock_destroy (&client);
    zsock_destroy (&server);
#endif

#if defined (__WINDOWS__)
    zsys_shutdown();
#endif
    //  @end

    printf ("OK\n");
}
示例#14
0
static void
s_self_handle_sink (self_t *self)
{
#if defined (ZMQ_EVENT_ALL)
#if (ZMQ_VERSION_MAJOR == 4)
    //  First frame is event number and value
    zframe_t *frame = zframe_recv (self->sink);
    int event = *(uint16_t *) (zframe_data (frame));
    int value = *(uint32_t *) (zframe_data (frame) + 2);
    //  Address is in second message frame
    char *address = zstr_recv (self->sink);
    zframe_destroy (&frame);

#elif (ZMQ_VERSION_MAJOR == 3 && ZMQ_VERSION_MINOR == 2)
    //  zmq_event_t is passed as-is in the frame
    zframe_t *frame = zframe_recv (self->sink);
    zmq_event_t *eptr = (zmq_event_t *) zframe_data (frame);
    int event = eptr->event;
    int value = eptr->data.listening.fd;
    char *address = strdup (eptr->data.listening.addr);
    assert (address);
    zframe_destroy (&frame);

#else
    //  We can't plausibly be here with other versions of libzmq
    assert (false);
#endif

    //  Now map event to text equivalent
    char *name;
    switch (event) {
        case ZMQ_EVENT_ACCEPTED:
            name = "ACCEPTED";
            break;
        case ZMQ_EVENT_ACCEPT_FAILED:
            name = "ACCEPT_FAILED";
            break;
        case ZMQ_EVENT_BIND_FAILED:
            name = "BIND_FAILED";
            break;
        case ZMQ_EVENT_CLOSED:
            name = "CLOSED";
            break;
        case ZMQ_EVENT_CLOSE_FAILED:
            name = "CLOSE_FAILED";
            break;
        case ZMQ_EVENT_DISCONNECTED:
            name = "DISCONNECTED";
            break;
        case ZMQ_EVENT_CONNECTED:
            name = "CONNECTED";
            break;
        case ZMQ_EVENT_CONNECT_DELAYED:
            name = "CONNECT_DELAYED";
            break;
        case ZMQ_EVENT_CONNECT_RETRIED:
            name = "CONNECT_RETRIED";
            break;
        case ZMQ_EVENT_LISTENING:
            name = "LISTENING";
            break;
#if (ZMQ_VERSION_MAJOR == 4)
        case ZMQ_EVENT_MONITOR_STOPPED:
            name = "MONITOR_STOPPED";
            break;
#endif
        default:
            zsys_error ("illegal socket monitor event: %d", event);
            name = "UNKNOWN";
            break;
    }
    if (self->verbose)
        zsys_info ("zmonitor: %s - %s", name, address);

    zstr_sendfm (self->pipe, "%s", name);
    zstr_sendfm (self->pipe, "%d", value);
    zstr_send (self->pipe, address);
    free (address);
#endif
}
示例#15
0
文件: zyre_node.c 项目: Muraad/zyre
static int
zyre_node_start (zyre_node_t *self)
{
    if (self->beacon_port) {
        //  Start beacon discovery
        //  ------------------------------------------------------------------
        assert (!self->beacon);
        self->beacon = zactor_new (zbeacon, NULL);
        if (!self->beacon)
            return 1;               //  Not possible to start beacon

        if (self->verbose)
            zsock_send (self->beacon, "s", "VERBOSE");
            
        //  Our hostname is provided by zbeacon
        zsock_send (self->beacon, "si", "CONFIGURE", self->beacon_port);
        char *hostname = zstr_recv (self->beacon);
        if (streq (hostname, ""))
            return -1;              //  No UDP broadcast interface available

        self->port = zsock_bind (self->inbox, "tcp://%s:*", hostname);
        zstr_free (&hostname);
        assert (self->port > 0);    //  Die on bad interface or port exhaustion
        assert (!self->endpoint);   //  If caller set this, we'd be using gossip
        self->endpoint = strdup (zsock_endpoint (self->inbox));

        //  Set broadcast/listen beacon
        beacon_t beacon;
        beacon.protocol [0] = 'Z';
        beacon.protocol [1] = 'R';
        beacon.protocol [2] = 'E';
        beacon.version = BEACON_VERSION;
        beacon.port = htons (self->port);
        zuuid_export (self->uuid, beacon.uuid);
        zsock_send (self->beacon, "sbi", "PUBLISH",
            (byte *) &beacon, sizeof (beacon_t), self->interval);
        zsock_send (self->beacon, "sb", "SUBSCRIBE", (byte *) "ZRE", 3);
        zpoller_add (self->poller, self->beacon);
    }
    else {
        //  Start gossip discovery
        //  ------------------------------------------------------------------
        //  If application didn't set an endpoint explicitly, grab ephemeral
        //  port on all available network interfaces.
        if (!self->endpoint) {
            const char *iface = zsys_interface ();
            if (streq (iface, ""))
                iface = "*";
            self->port = zsock_bind (self->inbox, "tcp://%s:*", iface);
            assert (self->port > 0);    //  Die on bad interface or port exhaustion

            char *hostname = zsys_hostname ();
            self->endpoint = zsys_sprintf ("tcp://%s:%d", hostname, self->port);
            zstr_free (&hostname);
        }
        assert (self->gossip);
        zstr_sendx (self->gossip, "PUBLISH", zuuid_str (self->uuid), self->endpoint, NULL);
        //  Start polling on zgossip
        zpoller_add (self->poller, self->gossip);
    }
    //  Start polling on inbox
    zpoller_add (self->poller, self->inbox);
    return 0;
}
示例#16
0
文件: zyre.c 项目: sphaero/zyre
void
zyre_test (bool verbose)
{
    printf (" * zyre: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    //  We'll use inproc gossip discovery so that this works without networking

    uint64_t version = zyre_version ();
    assert ((version / 10000) % 100 == ZYRE_VERSION_MAJOR);
    assert ((version / 100) % 100 == ZYRE_VERSION_MINOR);
    assert (version % 100 == ZYRE_VERSION_PATCH);

    //  Create two nodes
    zyre_t *node1 = zyre_new ("node1");
    assert (node1);
    assert (streq (zyre_name (node1), "node1"));
    zyre_set_header (node1, "X-HELLO", "World");
    if (verbose)
        zyre_set_verbose (node1);

    //  Set inproc endpoint for this node
    int rc = zyre_set_endpoint (node1, "inproc://zyre-node1");
    assert (rc == 0);
    //  Set up gossip network for this node
    zyre_gossip_bind (node1, "inproc://gossip-hub");
    rc = zyre_start (node1);
    assert (rc == 0);

    zyre_t *node2 = zyre_new ("node2");
    assert (node2);
    assert (streq (zyre_name (node2), "node2"));
    if (verbose)
        zyre_set_verbose (node2);

    //  Set inproc endpoint for this node
    //  First, try to use existing name, it'll fail
    rc = zyre_set_endpoint (node2, "inproc://zyre-node1");
    assert (rc == -1);
    //  Now use available name and confirm that it succeeds
    rc = zyre_set_endpoint (node2, "inproc://zyre-node2");
    assert (rc == 0);

    //  Set up gossip network for this node
    zyre_gossip_connect (node2, "inproc://gossip-hub");
    rc = zyre_start (node2);
    assert (rc == 0);
    assert (strneq (zyre_uuid (node1), zyre_uuid (node2)));

    zyre_join (node1, "GLOBAL");
    zyre_join (node2, "GLOBAL");

    //  Give time for them to interconnect
    zclock_sleep (250);
    if (verbose)
        zyre_dump (node1);

    zlist_t *peers = zyre_peers (node1);
    assert (peers);
    assert (zlist_size (peers) == 1);
    zlist_destroy (&peers);

    zyre_join (node1, "node1 group of one");
    zyre_join (node2, "node2 group of one");

    // Give them time to join their groups
    zclock_sleep (250);

    zlist_t *own_groups = zyre_own_groups (node1);
    assert (own_groups);
    assert (zlist_size (own_groups) == 2);
    zlist_destroy (&own_groups);

    zlist_t *peer_groups = zyre_peer_groups (node1);
    assert (peer_groups);
    assert (zlist_size (peer_groups) == 2);
    zlist_destroy (&peer_groups);

    char *value = zyre_peer_header_value (node2, zyre_uuid (node1), "X-HELLO");
    assert (streq (value, "World"));
    zstr_free (&value);

    //  One node shouts to GLOBAL
    zyre_shouts (node1, "GLOBAL", "Hello, World");

    //  Second node should receive ENTER, JOIN, and SHOUT
    zmsg_t *msg = zyre_recv (node2);
    assert (msg);
    char *command = zmsg_popstr (msg);
    assert (streq (command, "ENTER"));
    zstr_free (&command);
    assert (zmsg_size (msg) == 4);
    char *peerid = zmsg_popstr (msg);
    char *name = zmsg_popstr (msg);
    assert (streq (name, "node1"));
    zstr_free (&name);
    zframe_t *headers_packed = zmsg_pop (msg);

    char *address = zmsg_popstr (msg);
    char *endpoint = zyre_peer_address (node2, peerid);
    assert (streq (address, endpoint));
    zstr_free (&peerid);
    zstr_free (&endpoint);
    zstr_free (&address);

    assert (headers_packed);
    zhash_t *headers = zhash_unpack (headers_packed);
    assert (headers);
    zframe_destroy (&headers_packed);
    assert (streq ((char *) zhash_lookup (headers, "X-HELLO"), "World"));
    zhash_destroy (&headers);
    zmsg_destroy (&msg);

    msg = zyre_recv (node2);
    assert (msg);
    command = zmsg_popstr (msg);
    assert (streq (command, "JOIN"));
    zstr_free (&command);
    assert (zmsg_size (msg) == 3);
    zmsg_destroy (&msg);

    msg = zyre_recv (node2);
    assert (msg);
    command = zmsg_popstr (msg);
    assert (streq (command, "JOIN"));
    zstr_free (&command);
    assert (zmsg_size (msg) == 3);
    zmsg_destroy (&msg);

    msg = zyre_recv (node2);
    assert (msg);
    command = zmsg_popstr (msg);
    assert (streq (command, "SHOUT"));
    zstr_free (&command);
    zmsg_destroy (&msg);

    zyre_stop (node2);

    msg = zyre_recv (node2);
    assert (msg);
    command = zmsg_popstr (msg);
    assert (streq (command, "STOP"));
    zstr_free (&command);
    zmsg_destroy (&msg);

    zyre_stop (node1);

    zyre_destroy (&node1);
    zyre_destroy (&node2);

    printf ("OK\n");

#ifdef ZYRE_BUILD_DRAFT_API
    if (zsys_has_curve()){

        printf (" * zyre-curve: ");
        if (verbose)
            printf ("\n");

        if (verbose)
            zsys_debug("----------------TESTING CURVE --------------");

        zactor_t *speaker = zactor_new (zbeacon, NULL);
        assert (speaker);
        if (verbose)
            zstr_sendx (speaker, "VERBOSE", NULL);

        // ensuring we have a broadcast address
        zsock_send (speaker, "si", "CONFIGURE", 9999);
        char *hostname = zstr_recv (speaker);
        if (!*hostname) {
            printf ("OK (skipping test, no UDP broadcasting)\n");
            zactor_destroy (&speaker);
            freen (hostname);
            return;
        }
        freen (hostname);
        zactor_destroy (&speaker);


        // zap setup
        zactor_t *auth = zactor_new(zauth, NULL);
        assert (auth);

        if (verbose) {
            zstr_sendx(auth, "VERBOSE", NULL);
            zsock_wait(auth);
        }

        zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL);
        zsock_wait (auth);

        zyre_t *node3 = zyre_new ("node3");
        zyre_t *node4 = zyre_new ("node4");

        assert (node3);
        assert (node4);

        zyre_set_verbose (node3);
        zyre_set_verbose (node4);

        zyre_set_zap_domain(node3, "TEST");
        zyre_set_zap_domain(node4, "TEST");

        zsock_set_rcvtimeo(node3->inbox, 10000);
        zsock_set_rcvtimeo(node4->inbox, 10000);

        zcert_t *node3_cert = zcert_new ();
        zcert_t *node4_cert = zcert_new ();

        assert (node3_cert);
        assert (node4_cert);

        zyre_set_zcert(node3, node3_cert);
        zyre_set_zcert(node4, node4_cert);

        zyre_set_header(node3, "X-PUBLICKEY", "%s", zcert_public_txt(node3_cert));
        zyre_set_header(node4, "X-PUBLICKEY", "%s", zcert_public_txt(node4_cert));

        // test beacon
        if (verbose)
            zsys_debug ("----------------TESTING BEACON----------------");

        rc = zyre_start(node3);
        assert (rc == 0);

        rc = zyre_start(node4);
        assert (rc == 0);

        zyre_join (node3, "GLOBAL");
        zyre_join (node4, "GLOBAL");

        zclock_sleep (1500);

        if (verbose) {
            zyre_dump (node3);
            zyre_dump (node4);
        }

        zyre_shouts (node3, "GLOBAL", "Hello, World");

        //  Second node should receive ENTER, JOIN, and SHOUT
        msg = zyre_recv (node4);
        assert (msg);
        command = zmsg_popstr (msg);
        assert (streq (command, "ENTER"));
        zstr_free (&command);

        char *peerid = zmsg_popstr (msg);
        assert (peerid);
        name = zmsg_popstr (msg);
        assert (streq (name, "node3"));
        zmsg_destroy (&msg);

        msg = zyre_recv (node4);
        assert (msg);
        command = zmsg_popstr (msg);
        assert (streq (command, "JOIN"));
        zstr_free (&command);
        zmsg_destroy(&msg);

        msg = zyre_recv (node4);
        assert (msg);
        command = zmsg_popstr (msg);
        assert (streq (command, "SHOUT"));
        zstr_free (&command);
        zmsg_destroy(&msg);

        zyre_leave(node3, "GLOBAL");
        zyre_leave(node4, "GLOBAL");

        zstr_free (&name);
        zstr_free (&peerid);
        zstr_free (&command);

        zyre_stop (node3);
        zyre_stop (node4);

        // give things a chance to settle...
        zclock_sleep (250);

        zyre_destroy(&node3);
        zyre_destroy(&node4);

        zcert_destroy(&node3_cert);
        zcert_destroy(&node4_cert);

        // test gossip
        if (verbose)
            zsys_debug ("----------------TESTING GOSSIP----------------");

        zyre_t *node5 = zyre_new ("node5");
        zyre_t *node6 = zyre_new ("node6");

        assert (node5);
        assert (node6);

        if (verbose) {
            zyre_set_verbose (node5);
            zyre_set_verbose (node6);
        }

        // if it takes more than 10s, something probably went terribly wrong
        zsock_set_rcvtimeo(node5->inbox, 10000);
        zsock_set_rcvtimeo(node6->inbox, 10000);

        zcert_t *node5_cert = zcert_new ();
        zcert_t *node6_cert = zcert_new ();

        assert (node5_cert);
        assert (node6_cert);

        zyre_set_zcert(node5, node5_cert);
        zyre_set_zcert(node6, node6_cert);

        zyre_set_header(node5, "X-PUBLICKEY", "%s", zcert_public_txt(node5_cert));
        zyre_set_header(node6, "X-PUBLICKEY", "%s", zcert_public_txt(node6_cert));

        const char *gossip_cert = zcert_public_txt (node5_cert);

        // TODO- need to add zyre_gossip_port functions to get port from gossip bind(?)
        zyre_gossip_bind(node5, "tcp://127.0.0.1:9001");
        zyre_gossip_connect_curve(node6, gossip_cert, "tcp://127.0.0.1:9001");

        zyre_start(node5);
        zsock_wait(node5);
        zyre_start(node6);
        zsock_wait(node6);

        zyre_join (node5, "GLOBAL");
        zyre_join (node6, "GLOBAL");

        // give things a chance to settle...
        zclock_sleep (1500);

        if (verbose) {
            zyre_dump (node5);
            zyre_dump (node6);
        }

        zyre_shouts (node5, "GLOBAL", "Hello, World");

        //  Second node should receive ENTER, JOIN, and SHOUT
        msg = zyre_recv (node6);
        assert (msg);
        command = zmsg_popstr (msg);
        zsys_info(command);
        assert (streq (command, "ENTER"));
        zstr_free (&command);

        peerid = zmsg_popstr (msg);
        assert (peerid);
        name = zmsg_popstr (msg);
        zmsg_destroy (&msg);

        assert (streq (name, "node5"));
        zstr_free (&name);

        zyre_leave(node5, "GLOBAL");
        zyre_leave(node6, "GLOBAL");

        zyre_stop (node5);
        zyre_stop (node6);

        // give things a chance to settle...
        zclock_sleep (250);

        zstr_free (&peerid);

        zcert_destroy (&node5_cert);
        zcert_destroy (&node6_cert);

        zyre_destroy(&node5);
        zyre_destroy(&node6);
        zactor_destroy(&auth);

        printf ("OK\n");

    }
#endif
}
示例#17
0
int main (void)
{
    //  Initialize 0MQ context and virtual transport interface
    zctx_t *ctx = zctx_new ();
    assert (ctx);
    //  Run request-reply tests
    {
        zclock_log ("I: testing request-reply over TCP...");
        void *request = zthread_fork (ctx, test_tcp_req, NULL);
        void *reply = zthread_fork (ctx, test_tcp_rep, NULL);
        //  Send port number to use to each thread
        zstr_send (request, "32000");
        zstr_send (reply, "32000");
        sleep (1);
        zstr_send (request, "END");
        free (zstr_recv (request));
        zstr_send (reply, "END");
        free (zstr_recv (reply));
    }
    //  Run request-router tests
    {
        zclock_log ("I: testing request-router over TCP...");
        void *request = zthread_fork (ctx, test_tcp_req, NULL);
        void *router = zthread_fork (ctx, test_tcp_router, NULL);
        //  Send port number to use to each thread
        zstr_send (request, "32001");
        zstr_send (router, "32001");
        sleep (1);
        zstr_send (request, "END");
        free (zstr_recv (request));
        zstr_send (router, "END");
        free (zstr_recv (router));
    }
    //  Run request-dealer tests
    {
        zclock_log ("I: testing request-dealer over TCP...");
        void *request = zthread_fork (ctx, test_tcp_req, NULL);
        void *dealer = zthread_fork (ctx, test_tcp_dealer_srv, NULL);
        //  Send port number to use to each thread
        zstr_send (request, "32002");
        zstr_send (dealer, "32002");
        sleep (1);
        zstr_send (request, "END");
        free (zstr_recv (request));
        zstr_send (dealer, "END");
        free (zstr_recv (dealer));
    }
    //  Run dealer-router tests
    {
        zclock_log ("I: testing dealer-router over TCP...");
        void *dealer = zthread_fork (ctx, test_tcp_dealer_cli, NULL);
        void *router = zthread_fork (ctx, test_tcp_router, NULL);
        //  Send port number to use to each thread
        zstr_send (dealer, "32003");
        zstr_send (router, "32003");
        sleep (1);
        zstr_send (dealer, "END");
        free (zstr_recv (dealer));
        zstr_send (router, "END");
        free (zstr_recv (router));
    }
    //  Run push-pull tests
    {
        zclock_log ("I: testing push-pull over TCP...");
        void *pull1 = zthread_fork (ctx, test_tcp_pull, NULL);
        void *pull2 = zthread_fork (ctx, test_tcp_pull, NULL);
        void *push = zthread_fork (ctx, test_tcp_push, NULL);
        //  Send port number to use to each thread
        zstr_send (pull1, "32004");
        zstr_send (pull2, "32004");
        zstr_send (push, "32004");
        sleep (1);
        zstr_send (push, "END");
        free (zstr_recv (push));
        zstr_send (pull1, "END");
        free (zstr_recv (pull1));
        zstr_send (pull2, "END");
        free (zstr_recv (pull2));
    }
    //  Run pub-sub tests
    {
        zclock_log ("I: testing pub-sub over TCP...");
        void *sub1 = zthread_fork (ctx, test_tcp_sub, NULL);
        void *sub2 = zthread_fork (ctx, test_tcp_sub, NULL);
        void *pub = zthread_fork (ctx, test_tcp_pub, NULL);
        //  Send port number to use to each thread
        zstr_send (sub1, "32005");
        zstr_send (sub2, "32005");
        zstr_send (pub, "32005");
        sleep (1);
        zstr_send (pub, "END");
        free (zstr_recv (pub));
        zstr_send (sub1, "END");
        free (zstr_recv (sub1));
        zstr_send (sub2, "END");
        free (zstr_recv (sub2));
    }
    //  Run pair tests
    {
        zclock_log ("I: testing pair-pair over TCP...");
        void *pair1 = zthread_fork (ctx, test_tcp_pair_srv, NULL);
        void *pair2 = zthread_fork (ctx, test_tcp_pair_cli, NULL);
        //  Send port number to use to each thread
        zstr_send (pair1, "32006");
        zstr_send (pair2, "32006");
        sleep (1);
        zstr_send (pair1, "END");
        free (zstr_recv (pair1));
        zstr_send (pair2, "END");
        free (zstr_recv (pair2));
    }
    zctx_destroy (&ctx);
    return 0;
}
示例#18
0
文件: zsys.c 项目: wysman/czmq
void
zsys_test (bool verbose)
{
    printf (" * zsys: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    zsys_catch_interrupts ();

    //  Check capabilities without using the return value
    int rc = zsys_has_curve ();

    if (verbose) {
        char *hostname = zsys_hostname ();
        zsys_info ("host name is %s", hostname);
        free (hostname);
        zsys_info ("system limit is %zd ZeroMQ sockets", zsys_socket_limit ());
    }
    zsys_set_io_threads (1);
    zsys_set_max_sockets (0);
    zsys_set_linger (0);
    zsys_set_sndhwm (1000);
    zsys_set_rcvhwm (1000);
    zsys_set_pipehwm (2500);
    assert (zsys_pipehwm () == 2500);

    zsys_set_ipv6 (0);

    rc = zsys_file_delete ("nosuchfile");
    assert (rc == -1);

    bool rc_bool = zsys_file_exists ("nosuchfile");
    assert (rc_bool != true);

    rc = (int) zsys_file_size ("nosuchfile");
    assert (rc == -1);

    time_t when = zsys_file_modified (".");
    assert (when > 0);

    mode_t mode = zsys_file_mode (".");
    assert (S_ISDIR (mode));
    assert (mode & S_IRUSR);
    assert (mode & S_IWUSR);

    zsys_file_mode_private ();
    rc = zsys_dir_create ("%s/%s", ".", ".testsys/subdir");
    assert (rc == 0);
    when = zsys_file_modified ("./.testsys/subdir");
    assert (when > 0);
    assert (!zsys_file_stable ("./.testsys/subdir"));
    rc = zsys_dir_delete ("%s/%s", ".", ".testsys/subdir");
    assert (rc == 0);
    rc = zsys_dir_delete ("%s/%s", ".", ".testsys");
    assert (rc == 0);
    zsys_file_mode_default ();

    int major, minor, patch;
    zsys_version (&major, &minor, &patch);
    assert (major == CZMQ_VERSION_MAJOR);
    assert (minor == CZMQ_VERSION_MINOR);
    assert (patch == CZMQ_VERSION_PATCH);

    char *string = zsys_sprintf ("%s %02x", "Hello", 16);
    assert (streq (string, "Hello 10"));
    free (string);

    char *str64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,.";
    int num10 = 1234567890;
    string = zsys_sprintf ("%s%s%s%s%d", str64, str64, str64, str64, num10);
    assert (strlen (string) == (4 * 64 + 10));
    free (string);

    //  Test logging system
    zsys_set_logident ("czmq_selftest");
    zsys_set_logsender ("inproc://logging");
    void *logger = zsys_socket (ZMQ_SUB, NULL, 0);
    assert (logger);
    rc = zsocket_connect (logger, "inproc://logging");
    assert (rc == 0);
    rc = zmq_setsockopt (logger, ZMQ_SUBSCRIBE, "", 0);
    assert (rc == 0);

    if (verbose) {
        zsys_error ("This is an %s message", "error");
        zsys_warning ("This is a %s message", "warning");
        zsys_notice ("This is a %s message", "notice");
        zsys_info ("This is a %s message", "info");
        zsys_debug ("This is a %s message", "debug");
        zsys_set_logident ("hello, world");
        zsys_info ("This is a %s message", "info");
        zsys_debug ("This is a %s message", "debug");

        //  Check that logsender functionality is working
        char *received = zstr_recv (logger);
        assert (received);
        zstr_free (&received);
    }
    zsys_close (logger, NULL, 0);
    //  @end

    printf ("OK\n");
}
示例#19
0
static void handler (zsock_t *pipe, void *args) {
    curl_global_init(CURL_GLOBAL_ALL);
    CURLM *multi = curl_multi_init ();
    CURLSH *share = curl_share_init ();
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);

    long verbose = (*(bool *) args) ? 1L : 0L;
    long timeout = 30;
    CURLMcode code;

    SOCKET pipefd = zsock_fd (pipe);
    struct curl_waitfd waitfd = {pipefd, CURL_WAIT_POLLIN};

    //  List to hold pending curl handles, in case we are destroy the client
    //  while request are inprogress
    zlistx_t *pending_handles = zlistx_new ();
    zlistx_set_destructor (pending_handles, (zlistx_destructor_fn *) curl_destructor);

    zsock_signal (pipe, 0);

    bool terminated = false;
    while (!terminated) {
        int events = zsock_events (pipe);
        if ((events & ZMQ_POLLIN) == 0) {
            code = curl_multi_wait (multi, &waitfd, 1, 1000, NULL);
            assert (code == CURLM_OK);
        }

        events = zsock_events (pipe);
        if (events & ZMQ_POLLIN) {
            char* command = zstr_recv (pipe);
            if (!command)
                break;          //  Interrupted

            //  All actors must handle $TERM in this way
            if (streq (command, "$TERM"))
                terminated = true;
            else if (streq (command, "GET")) {
                char *url;
                zlistx_t *headers;
                void *userp;
                int rc = zsock_recv (pipe, "slp", &url, &headers, &userp);
                assert (rc == 0);

                zchunk_t *data = zchunk_new (NULL, 100);
                assert (data);
                struct curl_slist *curl_headers = zlistx_to_slist (headers);
                CURL *curl = curl_easy_init ();
                zlistx_add_end (pending_handles, curl);
                http_request *request = (http_request *) zmalloc (sizeof (http_request));
                assert (request);
                request->userp = userp;
                request->curl = curl;
                request->data = data;
                request->headers = curl_headers;

                curl_easy_setopt (curl, CURLOPT_SHARE, share);
                curl_easy_setopt (curl, CURLOPT_TIMEOUT, timeout);
                curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose);
                curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers);
                curl_easy_setopt (curl, CURLOPT_URL, url);
                curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
                curl_easy_setopt (curl, CURLOPT_WRITEDATA, data);
                curl_easy_setopt (curl, CURLOPT_PRIVATE, request);

                code = curl_multi_add_handle (multi, curl);
                assert (code == CURLM_OK);
                zlistx_destroy (&headers);
                zstr_free (&url);
           }
           else {
               puts ("E: invalid message to actor");
               assert (false);
           }
           zstr_free (&command);
        }

        int still_running;
        code = curl_multi_perform (multi, &still_running);
        assert (code == CURLM_OK);

        int msgq = 0;
        struct CURLMsg *msg = curl_multi_info_read(multi, &msgq);

        while (msg) {
            if(msg->msg == CURLMSG_DONE) {
                CURL *curl = msg->easy_handle;
                http_request *request;
                curl_easy_getinfo(curl, CURLINFO_PRIVATE, &request);

                long response_code_long;
                curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code_long);
                int response_code = (int)response_code_long;

                int rc = zsock_send (pipe, "icp", response_code, request->data, request->userp);
                assert (rc == 0);

                curl_multi_remove_handle (multi, curl);

                //  Remove curl from the pending handles and delete it
                void *handle = zlistx_find (pending_handles, curl);
                assert (handle);
                rc = zlistx_delete (pending_handles, handle);
                assert (rc == 0);
            }

            msg = curl_multi_info_read(multi, &msgq);
        }
    }

    zlistx_destroy (&pending_handles);
    curl_share_cleanup (share);
    curl_multi_cleanup (multi);
    curl_global_cleanup ();
}
示例#20
0
int main (int argc, char *argv [])
{
    //  Arguments can be either of:
    //      -p  primary server, at tcp://localhost:5001
    //      -b  backup server, at tcp://localhost:5002
    zctx_t *ctx = zctx_new ();
    void *statepub = zsocket_new (ctx, ZMQ_PUB);
    void *statesub = zsocket_new (ctx, ZMQ_SUB);
    zsockopt_set_subscribe (statesub, "");
    void *frontend = zsocket_new (ctx, ZMQ_ROUTER);
    bstar_t fsm = { 0 };

    if (argc == 2 && streq (argv [1], "-p")) {
        printf ("I: Primary master, waiting for backup (slave)\n");
        zsocket_bind (frontend, "tcp://*:5001");
        zsocket_bind (statepub, "tcp://*:5003");
        zsocket_connect (statesub, "tcp://localhost:5004");
        fsm.state = STATE_PRIMARY;
    }
    else
    if (argc == 2 && streq (argv [1], "-b")) {
        printf ("I: Backup slave, waiting for primary (master)\n");
        zsocket_bind (frontend, "tcp://*:5002");
        zsocket_bind (statepub, "tcp://*:5004");
        zsocket_connect (statesub, "tcp://localhost:5003");
        fsm.state = STATE_BACKUP;
    }
    else {
        printf ("Usage: bstarsrv { -p | -b }\n");
        zctx_destroy (&ctx);
        exit (0);
    }
    //  Set timer for next outgoing state message
    int64_t send_state_at = zclock_time () + HEARTBEAT;

    while (!zctx_interrupted) {
        zmq_pollitem_t items [] = {
            { frontend, 0, ZMQ_POLLIN, 0 },
            { statesub, 0, ZMQ_POLLIN, 0 }
        };
        int time_left = (int) ((send_state_at - zclock_time ()));
        if (time_left < 0)
            time_left = 0;
        int rc = zmq_poll (items, 2, time_left * ZMQ_POLL_MSEC);
        if (rc == -1)
            break;              //  Context has been shut down

        if (items [0].revents & ZMQ_POLLIN) {
            //  Have a client request
            zmsg_t *msg = zmsg_recv (frontend);
            fsm.event = CLIENT_REQUEST;
            if (s_state_machine (&fsm) == FALSE)
                //  Answer client by echoing request back
                zmsg_send (&msg, frontend);
            else
                zmsg_destroy (&msg);
        }
        if (items [1].revents & ZMQ_POLLIN) {
            //  Have state from our peer, execute as event
            char *message = zstr_recv (statesub);
            fsm.event = atoi (message);
            free (message);
            if (s_state_machine (&fsm))
                break;          //  Error, so exit
            fsm.peer_expiry = zclock_time () + 2 * HEARTBEAT;
        }
        //  If we timed-out, send state to peer
        if (zclock_time () >= send_state_at) {
            char message [2];
            sprintf (message, "%d", fsm.state);
            zstr_send (statepub, message);
            send_state_at = zclock_time () + HEARTBEAT;
        }
    }
    if (zctx_interrupted)
        printf ("W: interrupted\n");

    //  Shutdown sockets and context
    zctx_destroy (&ctx);
    return 0;
}
示例#21
0
文件: zproxy.c 项目: TangCheng/czmq
static void
s_proxy_task (void *args, zctx_t *ctx, void *command_pipe)
{
    //  Confirm to API that we've started up
    zsocket_signal (command_pipe);
    zproxy_t *self = (zproxy_t *) args;
    //  Capture socket, if not NULL, receives all data
    void *capture = NULL;

    //  Create poller to work on all three sockets
    zpoller_t *poller = zpoller_new (self->frontend, self->backend, command_pipe, NULL);

    bool stopped = false;
    while (!stopped) {
        //  Wait for activity on any polled socket, and read incoming message
        void *which = zpoller_wait (poller, -1);
        zmq_msg_t msg;
        zmq_msg_init (&msg);
        int send_flags;         //  Flags for outgoing message

        if (which && zmq_recvmsg (which, &msg, 0) != -1) {
            send_flags = zsocket_rcvmore (which)? ZMQ_SNDMORE: 0;
            if (which == self->frontend || which == self->backend) {
                void *output = which == self->frontend?
                    self->backend: self->frontend;

                //  Loop on all waiting messages, since polling adds a
                //  non-trivial cost per message, especially on OS/X
                while (true) {
                    if (capture) {
                        zmq_msg_t dup;
                        zmq_msg_init (&dup);
                        zmq_msg_copy (&dup, &msg);
                        if (zmq_sendmsg (capture, &dup, send_flags) == -1)
                            zmq_msg_close (&dup);
                    }
                    if (zmq_sendmsg (output, &msg, send_flags) == -1) {
                        zmq_msg_close (&msg);
                        break;
                    }
                    if (zmq_recvmsg (which, &msg, ZMQ_DONTWAIT) == -1)
                        break;      //  Presumably EAGAIN
                    send_flags = zsocket_rcvmore (which)? ZMQ_SNDMORE: 0;
                }
            }
            else
            if (which == command_pipe) {
                char command [10] = { 0 };
                assert (zmq_msg_size (&msg) < 10);
                memcpy (command, zmq_msg_data (&msg), zmq_msg_size (&msg));

                //  Execute API command
                if (streq (command, "PAUSE")) {
                    zpoller_destroy (&poller);
                    poller = zpoller_new (command_pipe, NULL);
                }
                else
                if (streq (command, "RESUME")) {
                    zpoller_destroy (&poller);
                    poller = zpoller_new (self->frontend, self->backend, command_pipe, NULL);
                }
                else
                if (streq (command, "CAPTURE")) {
                    //  Capture flow is always PUSH-to-PULL
                    capture = zsocket_new (self->ctx, ZMQ_PUSH);
                    char *endpoint = zstr_recv (command_pipe);
                    if (capture) {
                        int rc = zsocket_connect (capture, "%s", endpoint);
                        assert (rc == 0);
                    }
                    zstr_free (&endpoint);
                }
                else
                if (streq (command, "STOP"))
                    stopped = true;
                else
                    assert (0); //  Cannot happen, so die

                //  Signal to caller that we processed the command
                zsocket_signal (command_pipe);
            }
            else
                assert (0);     //  Cannot happen, so die
        }
        else
            break;              //  Interrupted
    }
    zpoller_destroy (&poller);
}
示例#22
0
int main (void)
{
    zctx_t *context = zctx_new ();
    void *frontend = zsocket_new (context, ZMQ_SUB);
    zsocket_bind (frontend, "ipc://frontend");
    void *backend = zsocket_new (context, ZMQ_XPUB);
    zsocket_bind (backend, "ipc://backend");

    //  .split main poll loop
    //  We route topic updates from frontend to backend, and
    //  we handle subscriptions by sending whatever we cached,
    //  if anything:
    while (true) {
	printf("Polling...\r\n");
        zmq_pollitem_t items [] = {
            { frontend, 0, ZMQ_POLLIN, 0 },
            { backend,  0, ZMQ_POLLIN, 0 }
        };
        if (zmq_poll (items, 2, -1) <= 0)
            break;              //  Interrupted(-1) or no event signaled (0)

	printf("Something read...\r\n");

        //  Any new topic data we cache and then forward
        if (items [0].revents & ZMQ_POLLIN) {
	    printf("Received... ");
            char *topic = zstr_recv (frontend);
            char *current = zstr_recv (frontend);
            if (!topic)
                break;
	    printf("%s : %s \r\n", topic, current);

	    zstr_sendm (backend, topic);
            zstr_send (backend, current);
            free (topic);
        }
        //  .split handle subscriptions
        //  When we get a new subscription, we pull data from the cache:
        if (items [1].revents & ZMQ_POLLIN) {
	    printf("Received new subscription...\r\n");
            zframe_t *frame = zframe_recv (backend);
            if (!frame)
                break;
            //  Event is one byte 0=unsub or 1=sub, followed by topic
            byte *event = zframe_data (frame);
            char *topic = zmalloc (zframe_size (frame));
            memcpy (topic, event + 1, zframe_size (frame) - 1);
            printf ("Topic is %s\n", topic);
	    if (event [0] == 0) {
                printf ("Unsubscribing topic %s\r\n", topic);
		zsocket_set_unsubscribe (frontend, topic);
	    }
	    if (event [0] == 1) {
                printf ("Subscribing topic %s\r\n", topic);
		zsocket_set_subscribe (frontend, topic);
            }
	    free(topic);
            zframe_destroy (&frame);
        }
    } 
    zctx_destroy (&context);
    return 0;
}
示例#23
0
int main(void)
{
  zctx_t* ctx = zctx_new();

  printf("I: connecting to server...\n");

  void* client = zsocket_new(ctx, ZMQ_REQ);
  assert(client);

  zsocket_connect(client, SERVER_ENDPOINT);

  int sequence = 0;
  int retries_left = REQUEST_RETRIES;

  while (retries_left && !zctx_interrupted) {
    // We send a request, then we work to get a reply.
    char request[10];

    sprintf(request, "%d", ++sequence);
    zstr_send(client, request);

    int expect_reply = 1;
    while (expect_reply) {
      // Poll socket for a reply, with timeout.
      zmq_pollitem_t items[] = { { client, 0, ZMQ_POLLIN, 0 } };
      int rc = zmq_poll(items, 1, REQUEST_TIMEOUT * ZMQ_POLL_MSEC);

      if (rc == -1) {
        break;          // Interrupted.
      }

      if (items[0].revents & ZMQ_POLLIN) {
        // We got a reply from the server, must match sequence.
        char* reply = zstr_recv(client);

        if (!reply) {
          break;        // Interrupted.
        }

        if (atoi(reply) == sequence) {
          printf("I: server replied OK (%s)\n", reply);
          retries_left = REQUEST_RETRIES;
          expect_reply = 0;
        } else {
          printf("E: malformed reply from server: %s\n", reply);
        }

        free(reply);
      } else if (--retries_left == 0) {
        printf("E: server seems to be offline, abandoning\n");
        break;
      } else {
        printf("W: no response from server, retrying...\n");

        // Old socket is confused; close it and open a new one.
        zsocket_destroy(ctx, client);

        printf("I: reconnecting to server...\n");
        client = zsocket_new(ctx, ZMQ_REQ);
        zsocket_connect(client, SERVER_ENDPOINT);

        // Send request again, on new socket.
        zstr_send(client, request);
      }
    }
  }

  zctx_destroy(&ctx);
  return 0;
}
示例#24
0
文件: imczmq.c 项目: henrid14/rsyslog
static rsRetVal addListener(instanceConf_t* iconf){
	struct lstn_s* pData;
	DEFiRet;

	CHKmalloc(pData=(struct lstn_s*)MALLOC(sizeof(struct lstn_s)));
	pData->next = NULL;
	pData->pRuleset = iconf->pBindRuleset;

	/* Create the zeromq socket */
	/* ------------------------ */

	pData->sock = zsock_new(iconf->sockType);
	if (!pData->sock) {
		errmsg.LogError(0, RS_RET_NO_ERRCODE,
				"imczmq: new socket failed for endpoints: %s",
				iconf->sockEndpoints);
		ABORT_FINALIZE(RS_RET_NO_ERRCODE);
	}

	DBGPRINTF ("imczmq: created socket...\n");

	/* Create the beacon actor if configured */
	/* ------------------------------------- */

	if((iconf->beacon != NULL) && (iconf->beaconPort > 0)) {
		DBGPRINTF ("imczmq: starting beacon actor...\n");

		pData->beaconActor = zactor_new(zbeacon, NULL);
		if (!pData->beaconActor) {
			errmsg.LogError(0, RS_RET_NO_ERRCODE,
					"imczmq: could not create beacon service");
			ABORT_FINALIZE (RS_RET_NO_ERRCODE);
		}

		zsock_send(pData->beaconActor, "si", "CONFIGURE", iconf->beaconPort);
		char *hostname = zstr_recv(pData->beaconActor);
		if (!*hostname) {
			errmsg.LogError(0, RS_RET_NO_ERRCODE,
					"imczmq: no UDP broadcasting available");
			ABORT_FINALIZE (RS_RET_NO_ERRCODE);
		}

		zsock_send(pData->beaconActor,
				"sbi", "PUBLISH", pData->beaconActor, strlen(iconf->beacon));

		DBGPRINTF ("omczmq: beacon is lit: hostname: '%s', port: '%d'...\n", 
			hostname, iconf->beaconPort);
	}



	DBGPRINTF("imczmq: authtype is: %s\n", iconf->authType);

	if (iconf->authType != NULL) {

		/* CURVESERVER */
		/* ----------- */

		if (!strcmp(iconf->authType, "CURVESERVER")) {

			zsock_set_zap_domain(pData->sock, "global");
			zsock_set_curve_server(pData->sock, 1);

			pData->serverCert = zcert_load(iconf->serverCertPath);
			
			if (!pData->serverCert) {
				errmsg.LogError(0, NO_ERRCODE, "could not load server cert");
				ABORT_FINALIZE(RS_RET_ERR);
			}

			zcert_apply(pData->serverCert, pData->sock);

			zstr_sendx(authActor, "CURVE", iconf->clientCertPath, NULL);
			zsock_wait(authActor);

			DBGPRINTF("imczmq: CURVESERVER: serverCertPath: '%s'\n", iconf->serverCertPath);
			DBGPRINTF("mczmq: CURVESERVER: clientCertPath: '%s'\n", iconf->clientCertPath);
		}

		/* CURVECLIENT */
		/* ----------- */

		else if (!strcmp(iconf->authType, "CURVECLIENT")) {
			if (!strcmp(iconf->clientCertPath, "*")) {
				pData->clientCert = zcert_new();
			}
			else {
				pData->clientCert = zcert_load(iconf->clientCertPath);
			}
			
			if (!pData->clientCert) {
				errmsg.LogError(0, NO_ERRCODE, "could not load client cert");
				ABORT_FINALIZE(RS_RET_ERR);
			}

			zcert_apply(pData->clientCert, pData->sock);
			pData->serverCert = zcert_load(iconf->serverCertPath);
			
			if (!pData->serverCert) {
				errmsg.LogError(0, NO_ERRCODE, "could not load server cert");
				ABORT_FINALIZE(RS_RET_ERR);
			}

			char *server_key = zcert_public_txt(pData->serverCert);
			zsock_set_curve_serverkey (pData->sock, server_key);

			DBGPRINTF("imczmq: CURVECLIENT: serverCertPath: '%s'\n", iconf->serverCertPath);
			DBGPRINTF("imczmq: CURVECLIENT: clientCertPath: '%s'\n", iconf->clientCertPath);
			DBGPRINTF("imczmq: CURVECLIENT: server_key: '%s'\n", server_key);
		}
		else {
			errmsg.LogError(0, NO_ERRCODE, "unrecognized auth type: '%s'", iconf->authType);
				ABORT_FINALIZE(RS_RET_ERR);
		}
	}

	/* subscribe to topics */
	/* ------------------- */

	if (iconf->sockType == ZMQ_SUB) {
		char topic[256], *list = iconf->topicList;
		while (list) {
			char *delimiter = strchr(list, ',');
			if (!delimiter) {
				delimiter = list + strlen (list);
			}

			if (delimiter - list > 255) {
				errmsg.LogError(0, NO_ERRCODE,
						"iconf->topicList must be under 256 characters");
				ABORT_FINALIZE(RS_RET_ERR);
			}
		
			memcpy(topic, list, delimiter - list);
			topic[delimiter - list] = 0;

			zsock_set_subscribe(pData->sock, topic);

			if (*delimiter == 0) {
				break;
			}

			list = delimiter + 1;
		}
	}

	switch (iconf->sockType) {
		case ZMQ_SUB:
			iconf->serverish = false;
			break;
		case ZMQ_PULL:
		case ZMQ_ROUTER:
			iconf->serverish = true;
			break;
	}


	int rc = zsock_attach(pData->sock, (const char*)iconf->sockEndpoints,
			iconf->serverish);
	if (rc == -1) {
		errmsg.LogError(0, NO_ERRCODE, "zsock_attach to %s",
				iconf->sockEndpoints);
		ABORT_FINALIZE(RS_RET_ERR);
	}

	/* add this struct to the global */
	/* ----------------------------- */

	if(lcnfRoot == NULL) {
		lcnfRoot = pData;
	} 
	if(lcnfLast == NULL) {
		lcnfLast = pData;
	} else {
		lcnfLast->next = pData;
		lcnfLast = pData;
	}

finalize_it:
	RETiRet;
}
示例#25
0
文件: zbeacon.c 项目: minhoryang/czmq
void
zbeacon_test (bool verbose)
{
    printf (" * zbeacon: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    //  Test 1 - two beacons, one speaking, one listening
    //  Create speaker beacon to broadcast our service
    zactor_t *speaker = zactor_new (zbeacon, NULL);
    assert (speaker);
    if (verbose)
        zstr_sendx (speaker, "VERBOSE", NULL);

    zsock_send (speaker, "si", "CONFIGURE", 9999);
    char *hostname = zstr_recv (speaker);
    if (!*hostname) {
        printf ("OK (skipping test, no UDP broadcasting)\n");
        zactor_destroy (&speaker);
        free (hostname);
        return;
    }
    free (hostname);

    //  Create listener beacon on port 9999 to lookup service
    zactor_t *listener = zactor_new (zbeacon, NULL);
    assert (listener);
    if (verbose)
        zstr_sendx (listener, "VERBOSE", NULL);
    zsock_send (listener, "si", "CONFIGURE", 9999);
    hostname = zstr_recv (listener);
    assert (*hostname);
    free (hostname);

    //  We will broadcast the magic value 0xCAFE
    byte announcement [2] = { 0xCA, 0xFE };
    zsock_send (speaker, "sbi", "PUBLISH", announcement, 2, 100);
    //  We will listen to anything (empty subscription)
    zsock_send (listener, "sb", "SUBSCRIBE", "", 0);

    //  Wait for at most 1/2 second if there's no broadcasting
    zsock_set_rcvtimeo (listener, 500);
    char *ipaddress = zstr_recv (listener);
    if (ipaddress) {
        zframe_t *content = zframe_recv (listener);
        assert (zframe_size (content) == 2);
        assert (zframe_data (content) [0] == 0xCA);
        assert (zframe_data (content) [1] == 0xFE);
        zframe_destroy (&content);
        zstr_free (&ipaddress);
        zstr_sendx (speaker, "SILENCE", NULL);
    }
    zactor_destroy (&listener);
    zactor_destroy (&speaker);

    //  Test subscription filter using a 3-node setup
    zactor_t *node1 = zactor_new (zbeacon, NULL);
    assert (node1);
    zsock_send (node1, "si", "CONFIGURE", 5670);
    hostname = zstr_recv (node1);
    assert (*hostname);
    free (hostname);

    zactor_t *node2 = zactor_new (zbeacon, NULL);
    assert (node2);
    zsock_send (node2, "si", "CONFIGURE", 5670);
    hostname = zstr_recv (node2);
    assert (*hostname);
    free (hostname);

    zactor_t *node3 = zactor_new (zbeacon, NULL);
    assert (node3);
    zsock_send (node3, "si", "CONFIGURE", 5670);
    hostname = zstr_recv (node3);
    assert (*hostname);
    free (hostname);

    zsock_send (node1, "sbi", "PUBLISH", "NODE/1", 6, 250);
    zsock_send (node2, "sbi", "PUBLISH", "NODE/2", 6, 250);
    zsock_send (node3, "sbi", "PUBLISH", "RANDOM", 6, 250);
    zsock_send (node1, "sb", "SUBSCRIBE", "NODE", 4);

    //  Poll on three API sockets at once
    zpoller_t *poller = zpoller_new (node1, node2, node3, NULL);
    assert (poller);
    int64_t stop_at = zclock_mono () + 1000;
    while (zclock_mono () < stop_at) {
        long timeout = (long) (stop_at - zclock_mono ());
        if (timeout < 0)
            timeout = 0;
        void *which = zpoller_wait (poller, timeout * ZMQ_POLL_MSEC);
        if (which) {
            assert (which == node1);
            char *ipaddress, *received;
            zstr_recvx (node1, &ipaddress, &received, NULL);
            assert (streq (received, "NODE/2"));
            zstr_free (&ipaddress);
            zstr_free (&received);
        }
    }
    zpoller_destroy (&poller);

    //  Stop listening
    zstr_sendx (node1, "UNSUBSCRIBE", NULL);

    //  Stop all node broadcasts
    zstr_sendx (node1, "SILENCE", NULL);
    zstr_sendx (node2, "SILENCE", NULL);
    zstr_sendx (node3, "SILENCE", NULL);

    //  Destroy the test nodes
    zactor_destroy (&node1);
    zactor_destroy (&node2);
    zactor_destroy (&node3);
    //  @end
    printf ("OK\n");
}
示例#26
0
文件: QmlZstr.cpp 项目: ht101996/czmq
///
//  Receive C string from socket. Caller must free returned string using
//  zstr_free(). Returns NULL if the context is being terminated or the 
//  process was interrupted.                                            
const QString QmlZstrAttached::recv (void *source) {
    return QString (zstr_recv (source));
};
示例#27
0
static void
node_actor (zsock_t *pipe, void *args)
{
    zyre_t *node = zyre_new (NULL);
    if (!node)
        return;                 //  Could not create new node
    zyre_set_verbose (node);

    zyre_set_endpoint (node, "inproc://%s", (char *) args);
    free (args);

    //  Connect to test hub
    zyre_gossip_connect (node, "inproc://zyre-hub");
    zyre_start (node);
    zsock_signal (pipe, 0);     //  Signal "ready" to caller

    int counter = 0;
    char *to_peer = NULL;        //  Either of these set,
    char *to_group = NULL;       //    and we set a message
    char *cookie = NULL;

    zpoller_t *poller = zpoller_new (pipe, zyre_socket (node), NULL);
    int64_t trigger = zclock_mono () + 1000;
    while (true) {
        void *which = zpoller_wait (poller, randof (1000));
        if (!which)
            break;              //  Interrupted

        //  $TERM from parent means exit; anything else is breach of
        //  contract so we should assert
        if (which == pipe) {
            char *command = zstr_recv (pipe);
            assert (streq (command, "$TERM"));
            zstr_free (&command);
            break;              //  Finished
        }
        //  Process an event from node
        if (which == zyre_socket (node)) {
            zmsg_t *incoming = zyre_recv (node);
            if (!incoming)
                break;          //  Interrupted

            char *event = zmsg_popstr (incoming);
            char *peer = zmsg_popstr (incoming);
            char *name = zmsg_popstr (incoming);
            if (streq (event, "ENTER"))
                //  Always say hello to new peer
                to_peer = strdup (peer);
            else
            if (streq (event, "EXIT"))
                //  Always try talk to departed peer
                to_peer = strdup (peer);
            else
            if (streq (event, "WHISPER")) {
                //  Send back response 1/2 the time
                if (randof (2) == 0) {
                    to_peer = strdup (peer);
                    cookie = zmsg_popstr (incoming);
                }
            }
            else
            if (streq (event, "SHOUT")) {
                to_peer = strdup (peer);
                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 *group = zmsg_popstr (incoming);
                printf ("I: %s joined %s\n", name, group);
                free (group);
            }
            else
            if (streq (event, "LEAVE")) {
                char *group = zmsg_popstr (incoming);
                printf ("I: %s left %s\n", name, group);
                free (group);
            }
            free (event);
            free (peer);
            free (name);
            zmsg_destroy (&incoming);

            //  Send outgoing messages if needed
            if (to_peer) {
                zyre_whispers (node, to_peer, "%d", counter++);
                free (to_peer);
                to_peer = NULL;
            }
            if (to_group) {
                zyre_shouts (node, to_group, "%d", counter++);
                free (to_group);
                to_group = NULL;
            }
            if (cookie) {
                free (cookie);
                cookie = NULL;
            }
        }
        if (zclock_mono () >= trigger) {
            trigger = zclock_mono () + 1000;
            char group [10];
            sprintf (group, "GROUP%03d", randof (MAX_GROUP));
            if (randof (4) == 0)
                zyre_join (node, group);
            else
            if (randof (3) == 0)
                zyre_leave (node, group);
        }
    }
    zpoller_destroy (&poller);
    zyre_destroy (&node);
}
示例#28
0
文件: lvcache.c 项目: Alexis-D/zguide
int main (void)
{
    zctx_t *context = zctx_new ();
    void *frontend = zsocket_new (context, ZMQ_SUB);
    zsocket_bind (frontend, "tcp://*:5557");
    void *backend = zsocket_new (context, ZMQ_XPUB);
    zsocket_bind (backend, "tcp://*:5558");

    //  Subscribe to every single topic from publisher
    zsocket_set_subscribe (frontend, "");

    //  Store last instance of each topic in a cache
    zhash_t *cache = zhash_new ();

    //  .split main poll loop
    //  We route topic updates from frontend to backend, and
    //  we handle subscriptions by sending whatever we cached,
    //  if anything:
    while (true) {
        zmq_pollitem_t items [] = {
            { frontend, 0, ZMQ_POLLIN, 0 },
            { backend,  0, ZMQ_POLLIN, 0 }
        };
        if (zmq_poll (items, 2, 1000 * ZMQ_POLL_MSEC) == -1)
            break;              //  Interrupted

        //  Any new topic data we cache and then forward
        if (items [0].revents & ZMQ_POLLIN) {
            char *topic = zstr_recv (frontend);
            char *current = zstr_recv (frontend);
            if (!topic)
                break;
            char *previous = zhash_lookup (cache, topic);
            if (previous) {
                zhash_delete (cache, topic);
                free (previous);
            }
            zhash_insert (cache, topic, current);
            zstr_sendm (backend, topic);
            zstr_send (backend, current);
            free (topic);
        }
        //  .split handle subscriptions
        //  When we get a new subscription we pull data from the cache:
        if (items [1].revents & ZMQ_POLLIN) {
            zframe_t *frame = zframe_recv (backend);
            if (!frame)
                break;
            //  Event is one byte 0=unsub or 1=sub, followed by topic
            byte *event = zframe_data (frame);
            if (event [0] == 1) {
                char *topic = zmalloc (zframe_size (frame));
                memcpy (topic, event + 1, zframe_size (frame) - 1);
                printf ("Sending cached topic %s\n", topic);
                char *previous = zhash_lookup (cache, topic);
                if (previous) {
                    zstr_sendm (backend, topic);
                    zstr_send (backend, previous);
                }
                free (topic);
            }
            zframe_destroy (&frame);
        }
    }
    zctx_destroy (&context);
    zhash_destroy (&cache);
    return 0;
}
示例#29
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: peering3 me {you}...\n");
        exit (EXIT_FAILURE);
    }
    self = argv [1];
    printf ("I: preparing broker at %s...\n", self);
    srandom ((unsigned) time (NULL));

    //  Prepare our context and sockets
    zctx_t *ctx = zctx_new ();
    char endpoint [256];

    //  Bind cloud frontend to endpoint
    void *cloudfe = zsocket_new (ctx, ZMQ_ROUTER);
    zsockopt_set_identity (cloudfe, self);
    zsocket_bind (cloudfe, "ipc://%s-cloud.ipc", self);

    //  Bind state backend / publisher to endpoint
    void *statebe = zsocket_new (ctx, ZMQ_PUB);
    zsocket_bind (statebe, "ipc://%s-state.ipc", self);

    //  Connect cloud backend to all peers
    void *cloudbe = zsocket_new (ctx, ZMQ_ROUTER);
    zsockopt_set_identity (cloudbe, self);
    int argn;
    for (argn = 2; argn < argc; argn++) {
        char *peer = argv [argn];
        printf ("I: connecting to cloud frontend at '%s'\n", peer);
        zsocket_connect (cloudbe, "ipc://%s-cloud.ipc", peer);
    }

    //  Connect statefe to all peers
    void *statefe = zsocket_new (ctx, ZMQ_SUB);
    for (argn = 2; argn < argc; argn++) {
        char *peer = argv [argn];
        printf ("I: connecting to state backend at '%s'\n", peer);
        zsocket_connect (statefe, "ipc://%s-state.ipc", peer);
    }
    //  Prepare local frontend and backend
    void *localfe = zsocket_new (ctx, ZMQ_ROUTER);
    zsocket_bind (localfe, "ipc://%s-localfe.ipc", self);

    void *localbe = zsocket_new (ctx, ZMQ_ROUTER);
    zsocket_bind (localbe, "ipc://%s-localbe.ipc", self);

    //  Prepare monitor socket
    void *monitor = zsocket_new (ctx, ZMQ_PULL);
    zsocket_bind (monitor, "ipc://%s-monitor.ipc", self);

    //  Start local workers
    int worker_nbr;
    for (worker_nbr = 0; worker_nbr < NBR_WORKERS; worker_nbr++)
        zthread_new (ctx, worker_task, NULL);

    //  Start local clients
    int client_nbr;
    for (client_nbr = 0; client_nbr < NBR_CLIENTS; client_nbr++)
        zthread_new (ctx, client_task, NULL);

    //  Interesting part
    //  -------------------------------------------------------------
    //  Publish-subscribe flow
    //  - Poll statefe and process capacity updates
    //  - Each time capacity changes, broadcast new value
    //  Request-reply flow
    //  - Poll primary and process local/cloud replies
    //  - While worker available, route localfe to local or cloud

    //  Queue of available workers
    int local_capacity = 0;
    int cloud_capacity = 0;
    zlist_t *workers = zlist_new ();

    while (1) {
        zmq_pollitem_t primary [] = {
            { localbe, 0, ZMQ_POLLIN, 0 },
            { cloudbe, 0, ZMQ_POLLIN, 0 },
            { statefe, 0, ZMQ_POLLIN, 0 },
            { monitor, 0, ZMQ_POLLIN, 0 }
        };
        //  If we have no workers anyhow, wait indefinitely
        int rc = zmq_poll (primary, 4,
                           local_capacity? 1000 * ZMQ_POLL_MSEC: -1);
        if (rc == -1)
            break;              //  Interrupted

        //  Track if capacity changes during this iteration
        int previous = local_capacity;

        //  Handle reply from local worker
        zmsg_t *msg = NULL;

        if (primary [0].revents & ZMQ_POLLIN) {
            msg = zmsg_recv (localbe);
            if (!msg)
                break;          //  Interrupted
            zframe_t *address = zmsg_unwrap (msg);
            zlist_append (workers, address);
            local_capacity++;

            //  If it's READY, don't route the message any further
            zframe_t *frame = zmsg_first (msg);
            if (memcmp (zframe_data (frame), LRU_READY, 1) == 0)
                zmsg_destroy (&msg);
        }
        //  Or handle reply from peer broker
        else if (primary [1].revents & ZMQ_POLLIN) {
            msg = zmsg_recv (cloudbe);
            if (!msg)
                break;          //  Interrupted
            //  We don't use peer broker address for anything
            zframe_t *address = zmsg_unwrap (msg);
            zframe_destroy (&address);
        }
        //  Route reply to cloud if it's addressed to a broker
        for (argn = 2; msg && argn < argc; argn++) {
            char *data = (char *) zframe_data (zmsg_first (msg));
            size_t size = zframe_size (zmsg_first (msg));
            if (size == strlen (argv [argn])
                    &&  memcmp (data, argv [argn], size) == 0)
                zmsg_send (&msg, cloudfe);
        }
        //  Route reply to client if we still need to
        if (msg)
            zmsg_send (&msg, localfe);

        //  Handle capacity updates
        if (primary [2].revents & ZMQ_POLLIN) {
            char *status = zstr_recv (statefe);
            cloud_capacity = atoi (status);
            free (status);
        }
        //  Handle monitor message
        if (primary [3].revents & ZMQ_POLLIN) {
            char *status = zstr_recv (monitor);
            printf ("%s\n", status);
            free (status);
        }

        //  Now route as many clients requests as we can handle
        //  - If we have local capacity we poll both localfe and cloudfe
        //  - If we have cloud capacity only, we poll just localfe
        //  - Route any request locally if we can, else to cloud
        //
        while (local_capacity + cloud_capacity) {
            zmq_pollitem_t secondary [] = {
                { localfe, 0, ZMQ_POLLIN, 0 },
                { cloudfe, 0, ZMQ_POLLIN, 0 }
            };
            if (local_capacity)
                rc = zmq_poll (secondary, 2, 0);
            else
                rc = zmq_poll (secondary, 1, 0);
            assert (rc >= 0);

            if (secondary [0].revents & ZMQ_POLLIN)
                msg = zmsg_recv (localfe);
            else if (secondary [1].revents & ZMQ_POLLIN)
                msg = zmsg_recv (cloudfe);
            else
                break;      //  No work, go back to primary

            if (local_capacity) {
                zframe_t *frame = (zframe_t *) zlist_pop (workers);
                zmsg_wrap (msg, frame);
                zmsg_send (&msg, localbe);
                local_capacity--;
            }
            else {
                //  Route to random broker peer
                int random_peer = randof (argc - 2) + 2;
                zmsg_pushmem (msg, argv [random_peer], strlen (argv [random_peer]));
                zmsg_send (&msg, cloudbe);
            }
        }
        if (local_capacity != previous) {
            //  We stick our own address onto the envelope
            zstr_sendm (statebe, self);
            //  Broadcast new capacity
            zstr_sendf (statebe, "%d", local_capacity);
        }
    }
    //  When we're done, clean up properly
    while (zlist_size (workers)) {
        zframe_t *frame = (zframe_t *) zlist_pop (workers);
        zframe_destroy (&frame);
    }
    zlist_destroy (&workers);
    zctx_destroy (&ctx);
    return EXIT_SUCCESS;
}
示例#30
0
文件: QmlZstr.cpp 项目: awynne/czmq
///
//  Receive C string from socket. Caller must free returned string using
//  zstr_free(). Returns NULL if the context is being terminated or the 
//  process was interrupted.                                            
QString QmlZstrAttached::recv (void *source) {
    char *retStr_ = zstr_recv (source);
    QString retQStr_ = QString (retStr_);
    free (retStr_);
    return retQStr_;
};