コード例 #1
0
ファイル: zbeacon.c プロジェクト: minhoryang/czmq
static int
s_self_handle_pipe (self_t *self)
{
    //  Get just the command off the pipe
    char *command = zstr_recv (self->pipe);
    if (!command)
        return -1;                  //  Interrupted

    if (self->verbose)
        zsys_info ("zbeacon: API command=%s", command);

    if (streq (command, "VERBOSE"))
        self->verbose = true;
    else
    if (streq (command, "CONFIGURE")) {
        int port;
        int rc = zsock_recv (self->pipe, "i", &port);
        assert (rc == 0);
        s_self_configure (self, port);
    }
    else
    if (streq (command, "PUBLISH")) {
        zframe_destroy (&self->transmit);
        zsock_recv (self->pipe, "fi", &self->transmit, &self->interval);
        assert (zframe_size (self->transmit) <= UDP_FRAME_MAX);
        if (self->interval == 0)
            self->interval = INTERVAL_DFLT;
        //  Start broadcasting immediately
        self->ping_at = zclock_mono ();
    }
    else
    if (streq (command, "SILENCE"))
        zframe_destroy (&self->transmit);
    else
    if (streq (command, "SUBSCRIBE")) {
        zframe_destroy (&self->filter);
        self->filter = zframe_recv (self->pipe);
        assert (zframe_size (self->filter) <= UDP_FRAME_MAX);
    }
    else
    if (streq (command, "UNSUBSCRIBE"))
        zframe_destroy (&self->filter);
    else
    if (streq (command, "$TERM"))
        self->terminated = true;
    else {
        zsys_error ("zbeacon: - invalid command: %s", command);
        assert (false);
    }
    zstr_free (&command);
    return 0;
}
コード例 #2
0
ファイル: mlm_server.c プロジェクト: karolhrdina/malamute
static void
check_for_mailbox_messages (client_t *self)
{
    if (*self->address) {
        zsock_send (self->server->mailbox, "ss", "QUERY", self->address);
        //  TODO: break into async reply back to server with client
        //  ID number that server can route to correct client, if it
        //  exists... we need some kind of internal async messaging
        //  to cover all different cases
        //  - engine_send_event (client, event, args)
        //  - stream return
        //  - mailbox to client
        //  - service request to client
        //  -> can each client have a DEALER socket?
        //  -> lookup/route on client unique name?
        //  -> server/client path? centralized for process?
        //  -> do we need lookup, or can we use ROUTER sockets?
        //  -> perhaps using ID?
        //  <<general model for internal messaging>>
        //  requirements, route by name, detect lost route?
        //  credit based flow control
        //  can send mlm_msg_t's all over the place
        zsock_recv (self->server->mailbox, "p", &self->msg);
        if (self->msg)
            engine_set_next_event (self, mailbox_message_event);
    }
}
コード例 #3
0
ファイル: zhttp_client.c プロジェクト: sphaero/czmq
int
zhttp_client_execute (zhttp_client_t *self) {
#ifdef HAVE_LIBCURL
    int response_code;
    zchunk_t *data;
    void *arg;
    zhttp_client_fn *handler;
    int rc;

    int events = zsock_events (self);

    while (zsock_has_in (self)) {
        rc = zsock_recv (self, "icpp", &response_code, &data, &handler, &arg);

        if (rc < 0)
            return rc;

        handler (arg, response_code, data);

        events = zsock_events (self);
    }

    return 0;
#else
    return -1;
#endif
}
コード例 #4
0
ファイル: zyre.c プロジェクト: sphaero/zyre
zlist_t *
zyre_peers (zyre_t *self)
{
    zlist_t *peers;
    zstr_send (self->actor, "PEERS");
    zsock_recv (self->actor, "p", &peers);
    return peers;
}
コード例 #5
0
ファイル: zyre.c プロジェクト: sphaero/zyre
zlist_t *
zyre_own_groups (zyre_t *self)
{
    zlist_t *groups;
    zstr_send (self->actor, "OWN GROUPS");
    zsock_recv (self->actor, "p", &groups);
    return groups;
}
コード例 #6
0
ファイル: zyre.c プロジェクト: sphaero/zyre
zlist_t *
zyre_peer_groups (zyre_t *self)
{
    zlist_t *groups;
    zstr_send (self->actor, "PEER GROUPS");
    zsock_recv (self->actor, "p", &groups);
    return groups;
}
コード例 #7
0
ファイル: zhttp_client.c プロジェクト: jimklimov/czmq
//  --------------------------------------------------------------------------
//  Receive the response for one of the requests. Blocks until a response is ready.
//  Use userp to identify the request.
int
zhttp_client_recv (zhttp_client_t *self, int *response_code, zchunk_t **data, void **userp) {
#ifdef HAVE_LIBCURL
    return zsock_recv (self, "icp", response_code, data, userp);
#else
    return -1;
#endif
}
コード例 #8
0
JNIEXPORT jint JNICALL
Java_org_zeromq_czmq_Zsock__1_1recv (JNIEnv *env, jclass c, jlong self, jstring picture)
{
    char *picture_ = (char *) (*env)->GetStringUTFChars (env, picture, NULL);
    jint recv_ = (jint) zsock_recv ((zsock_t *) (intptr_t) self, picture_);
    (*env)->ReleaseStringUTFChars (env, picture, picture_);
    return recv_;
}
コード例 #9
0
ファイル: zhttp_client.c プロジェクト: sphaero/czmq
static zchunk_t *
recv_http_request(void* server) {
    zchunk_t *routing_id;
    char *request;
    int rc = zsock_recv (server, "cs", &routing_id, &request);
    assert (rc == 0);

    while (strlen (request) == 0) {
        zchunk_destroy (&routing_id);
        zstr_free (&request);
        zsock_recv (server, "cs", &routing_id, &request);
        assert (rc == 0);
    }

    zstr_free (&request);

    return routing_id;
}
コード例 #10
0
ファイル: zyre.c プロジェクト: sphaero/zyre
zlist_t *
zyre_peers_by_group (zyre_t *self, const char *group)
{
    zlist_t *peers;
    zstr_sendm (self->actor, "GROUP PEERS");
    zstr_send (self->actor, group);
    zsock_recv (self->actor, "p", &peers);
    return peers;
}
コード例 #11
0
ファイル: mlm_server.c プロジェクト: karolhrdina/malamute
static void
server_configuration (server_t *self, zconfig_t *config)
{
    int dummy;
    mlm_msgq_cfg_configure (self->service_queue_cfg, config);
    zsock_send (self->mailbox, "sp", "CONFIGURE", config);
    // Wait for the mailbox to reconfigure itself so that the zconfig object
    // is not in use after we return
    zsock_recv (self->mailbox, "i", &dummy);
}
コード例 #12
0
ファイル: zyre.c プロジェクト: sphaero/zyre
char *
zyre_peer_address (zyre_t *self, const char *peer)
{
    assert (self);
    char *address;
    zstr_sendm (self->actor, "PEER ENDPOINT");
    zstr_send (self->actor, peer);
    zsock_recv (self->actor, "s", &address);
    return address;
}
コード例 #13
0
ファイル: zhttp_client.c プロジェクト: jimklimov/czmq
void
zhttp_client_test (bool verbose)
{
#if defined(HAVE_LIBCURL) && defined(ZMQ_STREAM)
    printf (" * zhttp_client: ");
    zsock_t *server = zsock_new_stream (NULL);
    int port = zsock_bind (server, "tcp://127.0.0.1:*");
    char url[255];
    sprintf (url, "http://127.0.0.1:%d", port);

    //  @selftest
    //  Simple create/destroy test
    zhttp_client_t *self = zhttp_client_new (verbose);
    assert (self);

    //  Send the get request
    zlistx_t *headers = zlistx_new ();
    zlistx_add_end (headers, "Host: zeromq.org");
    zhttp_client_get (self, url, headers, NULL);
    zlistx_destroy (&headers);

    //  Receive request on the server
    zchunk_t *routing_id;
    char *request;
    int rc = zsock_recv (server, "cs", &routing_id, &request);
    assert (rc == 0);

    //  Send the response
    char* response = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nHello";
    zsock_send (server, "cs", routing_id, response);

    //  Receive the response on the http client
    int code;
    zchunk_t *data;

    zhttp_client_recv (self, &code, &data, NULL);
    assert (zchunk_streq (data, "Hello"));

    //  Sending another request, without being answer
    //  Checking the client ability to stop while request are inprogres
    zhttp_client_get (self, url, NULL, NULL);

    zchunk_destroy (&data);
    zchunk_destroy (&routing_id);
    zstr_free (&request);
    zhttp_client_destroy (&self);
    zsock_destroy (&server);

    //  @end
    printf ("OK\n");
#endif
}
コード例 #14
0
ファイル: mlm_stream_simple.c プロジェクト: hurtonm/malamute
static int
s_stream_engine_handle_command (stream_engine_t *self)
{
    char *method = zstr_recv (self->cmdpipe);
    if (!method)
        return -1;              //  Interrupted; exit zloop
    if (self->verbose)
        zsys_debug ("mlm_stream_simple: API command=%s", method);

    if (streq (method, "VERBOSE"))
        self->verbose = true;       //  Start verbose logging
    else
    if (streq (method, "$TERM"))
        self->terminated = true;    //  Shutdown the engine
    else
    if (streq (method, "COMPILE")) {
        void *client;
        char *pattern;
        zsock_recv (self->cmdpipe, "ps", &client, &pattern);
        s_stream_engine_compile (self, client, pattern);
        zstr_free (&pattern);
    }
    else
    if (streq (method, "CANCEL")) {
        void *client;
        zsock_recv (self->cmdpipe, "p", &client);
        s_stream_engine_cancel (self, client);
    }
    //  Cleanup pipe if any argument frames are still waiting to be eaten
    if (zsock_rcvmore (self->cmdpipe)) {
        zsys_error ("mlm_stream_simple: trailing API command frames (%s)", method);
        zmsg_t *more = zmsg_recv (self->cmdpipe);
        zmsg_print (more);
        zmsg_destroy (&more);
    }
    zstr_free (&method);
    return self->terminated? -1: 0;
}
コード例 #15
0
ファイル: modusocket.c プロジェクト: AriZuu/micropython
STATIC mp_uint_t sock_read(mp_obj_t self_in, void *buf, mp_uint_t max_len, int *errcode) {
    socket_obj_t *socket = self_in;
    if (socket->ctx == -1) {
        // already closed
        *errcode = EBADF;
        return MP_STREAM_ERROR;
    }

    ssize_t recv_len = zsock_recv(socket->ctx, buf, max_len, 0);
    if (recv_len == -1) {
        *errcode = errno;
        return MP_STREAM_ERROR;
    }

    return recv_len;
}
コード例 #16
0
ファイル: zdir.c プロジェクト: diorcety/czmq
void
zdir_test (bool verbose)
{
    printf (" * zdir: ");

    //  @selftest
    // need to create a file in the test directory we're watching
    // in order to ensure the directory exists
    zfile_t *initfile = zfile_new ("./zdir-test-dir", "initial_file");
    assert (initfile);
    zfile_output (initfile);
    fprintf (zfile_handle (initfile), "initial file\n");
    zfile_close (initfile);
    zfile_destroy (&initfile);

    zdir_t *older = zdir_new ("zdir-test-dir", NULL);
    assert (older);
    if (verbose) {
        printf ("\n");
        zdir_dump (older, 0);
    }
    zdir_t *newer = zdir_new (".", NULL);
    assert (newer);
    zlist_t *patches = zdir_diff (older, newer, "/");
    assert (patches);
    while (zlist_size (patches)) {
        zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches);
        zdir_patch_destroy (&patch);
    }
    zlist_destroy (&patches);
    zdir_destroy (&older);
    zdir_destroy (&newer);

    zdir_t *nosuch = zdir_new ("does-not-exist", NULL);
    assert (nosuch == NULL);

    // zdir_watch test:
    zactor_t *watch = zactor_new (zdir_watch, NULL);
    assert (watch);

    int synced;
    if (verbose) {
        zsock_send (watch, "s", "VERBOSE");
        synced = zsock_wait(watch);
        assert ( synced == 0);
    }

    zclock_sleep (1001); // wait for initial file to become 'stable'

    zsock_send (watch, "si", "TIMEOUT", 100);
    synced = zsock_wait(watch);
    assert (synced == 0);

    zsock_send (watch, "ss", "SUBSCRIBE", "zdir-test-dir");
    synced = zsock_wait(watch);
    assert(synced == 0);

    zsock_send (watch, "ss", "UNSUBSCRIBE", "zdir-test-dir");
    synced = zsock_wait(watch);
    assert(synced == 0);

    zsock_send (watch, "ss", "SUBSCRIBE", "zdir-test-dir");
    synced = zsock_wait(watch);
    assert(synced == 0);

    zfile_t *newfile = zfile_new ("zdir-test-dir", "test_abc");
    zfile_output (newfile);
    fprintf (zfile_handle (newfile), "test file\n");
    zfile_close (newfile);

    zpoller_t *watch_poll = zpoller_new (watch, NULL);

    // poll for a certain timeout before giving up and failing the test.
    void* polled = zpoller_wait(watch_poll, 1001);
    assert (polled == watch);

    // wait for notification of the file being added
    char *path;
    int rc = zsock_recv (watch, "sp", &path, &patches);
    assert (rc == 0);

    assert (streq (path, "zdir-test-dir"));
    freen (path);

    assert (zlist_size (patches) == 1);

    zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches);
    assert (streq (zdir_patch_path (patch), "zdir-test-dir"));

    zfile_t *patch_file = zdir_patch_file (patch);
    assert (streq (zfile_filename (patch_file, ""), "zdir-test-dir/test_abc"));

    zdir_patch_destroy (&patch);
    zlist_destroy (&patches);

    // remove the file
    zfile_remove (newfile);
    zfile_destroy (&newfile);

    // poll for a certain timeout before giving up and failing the test.
    polled = zpoller_wait(watch_poll, 1001);
    assert (polled == watch);

    // wait for notification of the file being removed
    rc = zsock_recv (watch, "sp", &path, &patches);
    assert (rc == 0);

    assert (streq (path, "zdir-test-dir"));
    freen (path);

    assert (zlist_size (patches) == 1);

    patch = (zdir_patch_t *) zlist_pop (patches);
    assert (streq (zdir_patch_path (patch), "zdir-test-dir"));

    patch_file = zdir_patch_file (patch);
    assert (streq (zfile_filename (patch_file, ""), "zdir-test-dir/test_abc"));

    zdir_patch_destroy (&patch);
    zlist_destroy (&patches);

    zpoller_destroy (&watch_poll);
    zactor_destroy (&watch);

    // clean up by removing the test directory.
    zdir_t *testdir = zdir_new ("zdir-test-dir", NULL);
    zdir_remove (testdir, true);
    zdir_destroy (&testdir);

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

    printf ("OK\n");
}
コード例 #17
0
ファイル: hydrad.c プロジェクト: ZyreApps/hydra
int main (int argc, char *argv [])
{
    puts (PRODUCT);
    puts (COPYRIGHT);
    puts (NOWARRANTY);

    int argn = 1;
    if (argn < argc && streq (argv [argn], "-h")) {
        puts ("syntax: hydrad [-v] [-z] [ [-t] [-i] [-n HOSTNAME] directory ]");
        puts (" -- defaults to .hydra in current directory");
        puts (" -v = run Hydra protocol in verbose mode");
        puts (" -z = run Zyre discovery in verbose mode");
        puts (" -t = create some test posts");
        puts (" -i = run over ipc:// without networking");
        puts (" -n HOSTNAME = specify a custom hostname for hydrad to use");
        exit (0);
    }
    bool verbose = false;
    bool zverbose = false;
    bool testmode = false;
    bool localhost = false;
    bool lookforvalue = false;
    char *directory = ".hydra";
    char *hostname = NULL;
    while (argn < argc && (*argv [argn] == '-' || lookforvalue)) {
        if (streq (argv [argn], "-v"))
            verbose = true;
        else
        if (streq (argv [argn], "-z"))
            zverbose = true;
        else
        if (streq (argv [argn], "-t"))
            testmode = true;
        else
        if (streq (argv [argn], "-i"))
            localhost = true;
        else
        if (streq (argv [argn], "-n"))
            lookforvalue = true;
        else
        if (lookforvalue) {
            hostname = argv [argn];
            lookforvalue = false;
        }
        else {
            puts ("Invalid option, run hydrad -h to see options");
            exit (0);
        }
        argn++;
    }
    if (argn < argc)
        directory = argv [argn];
    
    hydra_t *hydra = hydra_new (directory);
    if (!hydra)
        exit (0);
    
    if (testmode) {
        //  Provision the Hydra server with some test posts in a tree
        char *post_id;
        zactor_t *server = zactor_new (hydra_server, NULL);
        zsock_send (server, "ssssss", "POST", "This is a string", "", "text/plain",
                    "string", "Hello, World");
        zsock_recv (server, "s", &post_id);

        zsock_send (server, "ssssss", "POST", "This is a disk file", post_id,
                    "text/zpl", "file", "hydra.cfg");
        zstr_free (&post_id);
        zsock_recv (server, "s", &post_id);

        zsock_send (server, "sssssb", "POST", "This is a blob of data", post_id,
                    "*/*", "chunk", "ABCDEFGHIJ", 10);
        zstr_free (&post_id);
        zsock_recv (server, "s", &post_id);
        zstr_free (&post_id);
        zactor_destroy (&server);
    }
    if (verbose)
        hydra_set_animate (hydra);
    if (zverbose)
        hydra_set_verbose (hydra);
    if (localhost)
        hydra_set_local_ipc (hydra);
    if (hostname)
        hydra_set_hostname (hydra, hostname);
    
    hydra_start (hydra);
    while (!zsys_interrupted)
        sleep (1);
    hydra_destroy (&hydra);
    
    return 0;
}
コード例 #18
0
ファイル: zhttp_client.c プロジェクト: jimklimov/czmq
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 ();
}
コード例 #19
0
ファイル: QmlZsock.cpp プロジェクト: awakecoding/czmq
///
//  Receive a 'picture' message to the socket (or actor). See zsock_send for
//  the format and meaning of the picture. Returns the picture elements into
//  a series of pointers as provided by the caller:                         
//                                                                          
//      i = int * (stores signed integer)                                   
//      4 = uint32_t * (stores 32-bit unsigned integer)                     
//      8 = uint64_t * (stores 64-bit unsigned integer)                     
//      s = char ** (allocates new string)                                  
//      b = byte **, size_t * (2 arguments) (allocates memory)              
//      c = zchunk_t ** (creates zchunk)                                    
//      f = zframe_t ** (creates zframe)                                    
//      U = zuuid_t * (creates a zuuid with the data)                       
//      h = zhashx_t ** (creates zhashx)                                    
//      p = void ** (stores pointer)                                        
//      m = zmsg_t ** (creates a zmsg with the remaing frames)              
//      z = null, asserts empty frame (0 arguments)                         
//      u = uint * (stores unsigned integer, deprecated)                    
//                                                                          
//  Note that zsock_recv creates the returned objects, and the caller must  
//  destroy them when finished with them. The supplied pointers do not need 
//  to be initialized. Returns 0 if successful, or -1 if it failed to recv  
//  a message, in which case the pointers are not modified. When message    
//  frames are truncated (a short message), sets return values to zero/null.
//  If an argument pointer is NULL, does not store any value (skips it).    
//  An 'n' picture matches an empty frame; if the message does not match,   
//  the method will return -1.                                              
int QmlZsock::recv (const QString &picture) {
    return zsock_recv (self, picture.toUtf8().data());
};
コード例 #20
0
ファイル: hydrad.c プロジェクト: mknoszlig/hydra
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;
}
コード例 #21
0
ファイル: qzmq.c プロジェクト: jaeheum/qzmq
Z K2(zsockrecv){PC(x); TC(y,-KS); R kj(zsock_recv(VSK(x), ys));}
コード例 #22
0
ファイル: zsock.c プロジェクト: HunterChen/czmq
void
zsock_test (bool verbose)
{
    printf (" * zsock: ");

    //  @selftest
    zsock_t *writer = zsock_new_push ("@tcp://127.0.0.1:5560");
    assert (writer);
    assert (zsock_resolve (writer) != writer);
    assert (streq (zsock_type_str (writer), "PUSH"));

    int rc;
#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (3,2,0))
    //  Check unbind
    rc = zsock_unbind (writer, "tcp://127.0.0.1:%d", 5560);
    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 = zsock_bind (writer, "tcp://127.0.0.1:%d", 5560);
    assert (rc == 5560);
    assert (streq (zsock_endpoint (writer), "tcp://127.0.0.1:5560"));
#endif

    zsock_t *reader = zsock_new_pull (">tcp://127.0.0.1:5560");
    assert (reader);
    assert (zsock_resolve (reader) != reader);
    assert (streq (zsock_type_str (reader), "PULL"));

    zstr_send (writer, "Hello, World");
    zmsg_t *msg = zsock_recv (reader);
    assert (msg);
    char *string = zmsg_popstr (msg);
    assert (streq (string, "Hello, World"));
    free (string);
    zmsg_destroy (&msg);

    //  Test binding to ephemeral ports, sequential and random
    int port = zsock_bind (writer, "tcp://127.0.0.1:*");
    assert (port >= DYNAMIC_FIRST && port <= DYNAMIC_LAST);
    port = zsock_bind (writer, "tcp://127.0.0.1:*[50000-]");
    assert (port >= 50000 && port <= DYNAMIC_LAST);
    port = zsock_bind (writer, "tcp://127.0.0.1:*[-50001]");
    assert (port >= DYNAMIC_FIRST && port <= 50001);
    port = zsock_bind (writer, "tcp://127.0.0.1:*[60000-60010]");
    assert (port >= 60000 && port <= 60010);
    
    port = zsock_bind (writer, "tcp://127.0.0.1:!");
    assert (port >= DYNAMIC_FIRST && port <= DYNAMIC_LAST);
    port = zsock_bind (writer, "tcp://127.0.0.1:![50000-]");
    assert (port >= 50000 && port <= DYNAMIC_LAST);
    port = zsock_bind (writer, "tcp://127.0.0.1:![-50001]");
    assert (port >= DYNAMIC_FIRST && port <= 50001);
    port = zsock_bind (writer, "tcp://127.0.0.1:![60000-60010]");
    assert (port >= 60000 && port <= 60010);

    //  Test zsock_endpoint method
    rc = zsock_bind (writer, "inproc://test.%s", "writer");
    assert (rc == 0);
    assert (streq (zsock_endpoint (writer), "inproc://test.writer"));
    
    //  Test error state when connecting to an invalid socket type
    //  ('txp://' instead of 'tcp://', typo intentional)
    rc = zsock_connect (reader, "txp://127.0.0.1:5560");
    assert (rc == -1);

    rc = zsock_signal (writer, 123);
    assert (rc == 0);
    rc = zsock_wait (reader);
    assert (rc == 123);

    zsock_destroy (&reader);
    zsock_destroy (&writer);

    //  Test zsock_attach method
    zsock_t *server = zsock_new (ZMQ_DEALER);
    rc = zsock_attach (server, "@inproc://myendpoint,tcp://127.0.0.1:5556,inproc://others", true);
    assert (rc == 0);
    rc = zsock_attach (server, "", false);
    assert (rc == 0);
    rc = zsock_attach (server, NULL, true);
    assert (rc == 0);
    rc = zsock_attach (server, ">a,@b, c,, ", false);
    assert (rc == -1);
    zsock_destroy (&server);
    //  @end

    printf ("OK\n");
}