Example #1
0
File: ui.c Project: miska/alice
int main(int argc, char **argv)
{
    if(argc != 2) {
        fprintf(stderr, "Usage: %s address\n", argv[0]);
        exit(1);
    }

    char *addr = argv[1];

    mlm_client_t *agent = mlm_client_new ();
    // mlm_client_connect () returns -1 on failure
    if ( mlm_client_connect (agent, addr, 1000, "UI") == -1 ) {
        zsys_error ("Cannot connect to the endpoint %s", addr);
        mlm_client_destroy (&agent);
        return EXIT_FAILURE;
    }
    zmsg_t *getmsg = zmsg_new();
    zmsg_addstr(getmsg, "GET");
    zmsg_addstr(getmsg, "temperature");
    // mlm_client_sendfor () returns zero on success
    if (mlm_client_sendfor (agent, "stats", "temperature", NULL, 0, &getmsg) !=0 ) {
        zsys_error ("Cannot send the message");
        mlm_client_destroy (&agent);
        return 1;
    }
    getmsg = zmsg_new();
    zmsg_addstr(getmsg, "GET");
    zmsg_addstr(getmsg, "ups.state");
    if (mlm_client_sendfor (agent, "stats", "ups.state", NULL, 0, &getmsg) != 0) {
        zsys_error ("Cannot send the message");
        mlm_client_destroy (&agent);
        return 1;
    }
    getmsg = zmsg_new();
    zmsg_addstr(getmsg, "GET");
    zmsg_addstr(getmsg, "ups.power");
    if (mlm_client_sendfor (agent, "stats", "ups.power", NULL, 0, &getmsg) != 0) {
        zsys_error ("Cannot send the message");
        mlm_client_destroy (&agent);
        return 1;
    }

    // need to read replies, waiying for 3 of them
    int i = 0;
    while ( !zsys_interrupted && i < 3 )
    {
        zsys_info ("waiting for %d reply message", i);
        zmsg_t *msg = mlm_client_recv (agent);
        if ( msg == NULL )
            continue;
        if ( streq (mlm_client_command (agent), "MAILBOX DELIVER") )
        {
            if ( ( strcmp(mlm_client_subject(agent), "temperature") == 0 ) ||
                 ( strcmp(mlm_client_subject(agent), "ups.power") == 0 ) ||
                 ( strcmp(mlm_client_subject(agent), "ups.temperature") == 0 ) )
            {
                char *key = zmsg_popstr (msg);
                char *result = zmsg_popstr (msg);
                zsys_info ("GOT: %s = %s", key , result);
                i++;
            }
        }
        zmsg_destroy (&msg);
    }
    mlm_client_destroy (&agent);
    return 0;
}
Example #2
0
int main (int argc, char *argv [])
{
    //  Let's start a new Malamute broker
    zactor_t *broker = zactor_new (mlm_server, NULL);

    //  Switch on verbose tracing... this gets a little overwhelming so you
    //  can comment or delete this when you're bored with it:
    zsock_send (broker, "s", "VERBOSE");

    //  We control the broker by sending it commands. It's a CZMQ actor, and
    //  we can talk to it using the zsock API (or zstr, or zframe, or zmsg).
    //  To get things started, let's tell the broker to bind to an endpoint:
//     zsock_send (broker, "ss", "BIND", "tcp://*:12345");

    //  This is how we configure a server from an external config file, which
    //  is in http://rfc.zeromq.org/spec:4/ZPL format:
    zstr_sendx (broker, "LOAD", "src/malamute.cfg", NULL);

    //  We can also, or alternatively, set server properties by sending it
    //  SET commands like this (see malamute.cfg for details):
    zsock_send (broker, "sss", "SET", "server/timeout", "5000");

    //  For PLAIN authentication, we start a zauth instance. This handles
    //  all client connection requests by checking against a password file
    zactor_t *auth = zactor_new (zauth, NULL);
    assert (auth);

    //  We can switch on verbose tracing to debug authentication errors
    zstr_sendx (auth, "VERBOSE", NULL);
    zsock_wait (auth);

    //  Now specify the password file; each line says 'username=password'
    zstr_sendx (auth, "PLAIN", "src/passwords.cfg", NULL);
    zsock_wait (auth);

    //  The broker is now running. Let's start two clients, one to publish
    //  messages and one to receive them. We're going to test the stream
    //  pattern with some natty wildcard patterns.
    mlm_client_t *reader = mlm_client_new ();
    assert (reader);
    int rc = mlm_client_set_plain_auth (reader, "reader", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (reader, "tcp://127.0.0.1:9999", 1000, "reader");
    assert (rc == 0);

    mlm_client_t *writer = mlm_client_new ();
    assert (writer);
    rc = mlm_client_set_plain_auth (writer, "writer", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (writer, "tcp://127.0.0.1:9999", 1000, "writer");
    assert (rc == 0);

    //  The writer publishes to the "weather" stream
    mlm_client_set_producer (writer, "weather");

    //  The reader consumes temperature messages off the "weather" stream
    mlm_client_set_consumer (reader, "weather", "temp.*");

    //  The writer sends a series of messages with various subjects. The
    //  sendx method sends string data to the stream (we send the subject,
    //  then one or more strings):
    mlm_client_sendx (writer, "temp.moscow", "1", NULL);
    mlm_client_sendx (writer, "rain.moscow", "2", NULL);
    mlm_client_sendx (writer, "temp.madrid", "3", NULL);
    mlm_client_sendx (writer, "rain.madrid", "4", NULL);
    mlm_client_sendx (writer, "temp.london", "5", NULL);
    mlm_client_sendx (writer, "rain.london", "6", NULL);

    //  The simplest way to receive a message is via the recvx method,
    //  which stores multipart string data:
    char *subject, *content;
    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "temp.moscow"));
    assert (streq (content, "1"));
    zstr_free (&subject);
    zstr_free (&content);

    //  The last-received message has other properties:
    assert (streq (mlm_client_subject (reader), "temp.moscow"));
    assert (streq (mlm_client_command (reader), "STREAM DELIVER"));
    assert (streq (mlm_client_sender (reader), "writer"));
    assert (streq (mlm_client_address (reader), "weather"));

    //  Let's get the other two messages:
    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "temp.madrid"));
    assert (streq (content, "3"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "temp.london"));
    assert (streq (content, "5"));
    zstr_free (&subject);
    zstr_free (&content);

    //  Great, it all works. Now to shutdown, we use the destroy method,
    //  which does a proper deconnect handshake internally:
    mlm_client_destroy (&reader);
    mlm_client_destroy (&writer);

    //  Finally, shut down the broker by destroying the actor; this does
    //  a proper shutdown so that all memory is freed as you'd expect.
    zactor_destroy (&broker);
    zactor_destroy (&auth);
    return 0;
}
Example #3
0
//  ---------------------------------------------------------------------------
//  Selftest
void
mlm_client_test (bool verbose)
{
    printf (" * mlm_client: \n");

    //  @selftest
    mlm_client_verbose = verbose;

    //  Start a server to test against, and bind to endpoint
    zactor_t *server = zactor_new (mlm_server, "mlm_client_test");
    if (verbose)
        zstr_send (server, "VERBOSE");
    zstr_sendx (server, "LOAD", "src/mlm_client.cfg", NULL);

    //  Install authenticator to test PLAIN access
    zactor_t *auth = zactor_new (zauth, NULL);
    assert (auth);
    if (verbose) {
        zstr_sendx (auth, "VERBOSE", NULL);
        zsock_wait (auth);
    }
    zstr_sendx (auth, "PLAIN", "src/passwords.cfg", NULL);
    zsock_wait (auth);

    /////
    // Test mutual address exchange
    /**
       -----------                                                                                             ----------

       | Frontend | -> 1) provide addr, req opp addr   ->  |\         / |  <-  1) Provide addr, Req opp addr  | Backend |
                                                              >Broker<                                              
       -----------     2) Receive opp addr             <-                  -> 2) Receive opposite address      ----------
       
       3) Direct connection establishment
       -----------              ----------- 
                                            
       | Frontend | <- Send -> | Backend |
                                            
       -----------              ----------- 

     */
    mlm_client_t *frontend = mlm_client_new ();
    assert(frontend);
    mlm_client_t *backend = mlm_client_new();
    assert(backend);

    // connect front side to broker
    printf("connecting frontend to broker\n");
    int rc = mlm_client_set_plain_auth (frontend, "writer", "secret");
    assert (rc == 0);
    rc=mlm_client_connect (frontend, "tcp://127.0.0.1:9999", 1000, "");
    assert (rc == 0);

    // connect back side to broker    
    printf("connecting backend to broker\n");
    rc = mlm_client_set_plain_auth (backend, "reader", "secret");
    assert (rc == 0);
    rc=mlm_client_connect (backend, "tcp://127.0.0.1:9999", 1000, "");
    assert (rc == 0);
    
    //before you ever set a service, you should've already called bind in order to facilitate a 
    // connection from the other side. In this way, it's causally correct.
    // the frontend tells the broker that it is interested in addresses that are on the other side
    printf("setting frontend service\n");
    mlm_client_set_worker(frontend, "backendEndpoints", "SET*");
    // the backend tells the broker that it is interested in addresses that are on the other side
    printf("setting backend service\n");
    mlm_client_set_worker(backend, "frontendEndpoints", "SET*");
    
    // the frontend tells the broker what it's address is, fulfilling a need that the backend set;
    //  consequently, the broker sends this to the backend, which has set a service that it is
    //  subscribed to. SET* matches SET
    printf("sending frontend address SET message\n");
    mlm_client_sendforx(frontend, "frontendEndpoints", "SET", "inproc://frontend", NULL);
    // the backend tells the broker what it's address is, fullfilling a need that the frontend set;
    //  consequently, the broker sends this to the frontend, which has reported a service to the broker
    //  the broker matches SET to SET*.
    printf("sending backend address SET message\n");
    mlm_client_sendforx(backend, "backendEndpoints", "SET", "inproc://backend", NULL);
    
    char *set=NULL, *opp_addr=NULL;
    printf("receiving on backend");
    mlm_client_recvx(backend, &set, &opp_addr, NULL);
    assert(set); 
    assert(opp_addr); 
    // connect backend to frontend here, then clean up
    zstr_free(&opp_addr);
    zstr_free(&set);

    printf("receiving on backend");
    mlm_client_recvx(frontend, &set, &opp_addr, NULL);
    assert(set);
    assert(opp_addr);
    // connect frontend to backend here, then clean up
    zstr_free(&opp_addr);
    zstr_free(&set);

    // cleanup
    mlm_client_destroy(&backend);
    mlm_client_destroy(&frontend);
    
    // End of mutual address exchange tests
    /////
    
    //  Test stream pattern
    mlm_client_t *writer = mlm_client_new ();
    assert (writer);
    rc = mlm_client_set_plain_auth (writer, "writer", "secret");
    assert (rc == 0);
    assert (mlm_client_connected (writer) == false);
    rc = mlm_client_connect (writer, "tcp://127.0.0.1:9999", 1000, "writer");
    assert (rc == 0);
    assert (mlm_client_connected (writer) == true);

    mlm_client_t *reader = mlm_client_new ();
    assert (reader);
    rc = mlm_client_set_plain_auth (reader, "reader", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (reader, "tcp://127.0.0.1:9999", 1000, "");
    assert (rc == 0);

    mlm_client_set_producer (writer, "weather");
    mlm_client_set_consumer (reader, "weather", "temp.*");

    mlm_client_sendx (writer, "temp.moscow", "1", NULL);
    mlm_client_sendx (writer, "rain.moscow", "2", NULL);
    mlm_client_sendx (writer, "temp.madrid", "3", NULL);
    mlm_client_sendx (writer, "rain.madrid", "4", NULL);
    mlm_client_sendx (writer, "temp.london", "5", NULL);
    mlm_client_sendx (writer, "rain.london", "6", NULL);

    char *subject, *content;
    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "temp.moscow"));
    assert (streq (content, "1"));
    assert (streq (mlm_client_command (reader), "STREAM DELIVER"));
    assert (streq (mlm_client_sender (reader), "writer"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "temp.madrid"));
    assert (streq (content, "3"));
    assert (streq (mlm_client_command (reader), "STREAM DELIVER"));
    assert (streq (mlm_client_subject (reader), "temp.madrid"));
    assert (streq (mlm_client_sender (reader), "writer"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "temp.london"));
    assert (streq (content, "5"));
    assert (streq (mlm_client_command (reader), "STREAM DELIVER"));
    assert (streq (mlm_client_sender (reader), "writer"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_destroy (&reader);

    //  Test mailbox pattern
    reader = mlm_client_new ();
    assert (reader);
    rc = mlm_client_set_plain_auth (reader, "reader", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (reader, "tcp://127.0.0.1:9999", 1000, "mailbox");
    assert (rc == 0);

    mlm_client_sendtox (writer, "mailbox", "subject 1", "Message 1", "attachment", NULL);

    char *attach;
    mlm_client_recvx (reader, &subject, &content, &attach, NULL);
    assert (streq (subject, "subject 1"));
    assert (streq (content, "Message 1"));
    assert (streq (attach, "attachment"));
    assert (streq (mlm_client_command (reader), "MAILBOX DELIVER"));
    assert (streq (mlm_client_subject (reader), "subject 1"));
    assert (streq (mlm_client_sender (reader), "writer"));
    zstr_free (&subject);
    zstr_free (&content);
    zstr_free (&attach);

    //  Now test that mailbox survives reader disconnect
    mlm_client_destroy (&reader);
    mlm_client_sendtox (writer, "mailbox", "subject 2", "Message 2", NULL);
    mlm_client_sendtox (writer, "mailbox", "subject 3", "Message 3", NULL);

    reader = mlm_client_new ();
    assert (reader);
    rc = mlm_client_set_plain_auth (reader, "reader", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (reader, "tcp://127.0.0.1:9999", 500, "mailbox");
    assert (rc == 0);

    mlm_client_recvx (reader, &subject, &content, &attach, NULL);
    assert (streq (subject, "subject 2"));
    assert (streq (content, "Message 2"));
    assert (streq (mlm_client_command (reader), "MAILBOX DELIVER"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_recvx (reader, &subject, &content, &attach, NULL);
    assert (streq (subject, "subject 3"));
    assert (streq (content, "Message 3"));
    assert (streq (mlm_client_command (reader), "MAILBOX DELIVER"));
    zstr_free (&subject);
    zstr_free (&content);

    //  Test service pattern
    mlm_client_set_worker (reader, "printer", "bw.*");
    mlm_client_set_worker (reader, "printer", "color.*");

    mlm_client_sendforx (writer, "printer", "bw.A4", "Important contract", NULL);
    mlm_client_sendforx (writer, "printer", "bw.A5", "Special conditions", NULL);

    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "bw.A4"));
    assert (streq (content, "Important contract"));
    assert (streq (mlm_client_command (reader), "SERVICE DELIVER"));
    assert (streq (mlm_client_sender (reader), "writer"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "bw.A5"));
    assert (streq (content, "Special conditions"));
    assert (streq (mlm_client_command (reader), "SERVICE DELIVER"));
    assert (streq (mlm_client_sender (reader), "writer"));
    zstr_free (&subject);
    zstr_free (&content);

    //  Test that writer shutdown does not cause message loss
    mlm_client_set_consumer (reader, "weather", "temp.*");
    mlm_client_sendx (writer, "temp.brussels", "7", NULL);
    mlm_client_destroy (&writer);

    mlm_client_recvx (reader, &subject, &content, NULL);
    assert (streq (subject, "temp.brussels"));
    assert (streq (content, "7"));
    zstr_free (&subject);
    zstr_free (&content);
    mlm_client_destroy (&reader);

    //  Test multiple readers and multiple writers
    mlm_client_t *writer1 = mlm_client_new ();
    assert (writer1);
    rc = mlm_client_set_plain_auth (writer1, "writer", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (writer1, "tcp://127.0.0.1:9999", 1000, "");
    assert (rc == 0);

    mlm_client_t *writer2 = mlm_client_new ();
    assert (writer2);
    rc = mlm_client_set_plain_auth (writer2, "writer", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (writer2, "tcp://127.0.0.1:9999", 1000, "");
    assert (rc == 0);

    mlm_client_t *reader1 = mlm_client_new ();
    assert (reader1);
    rc = mlm_client_set_plain_auth (reader1, "reader", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (reader1, "tcp://127.0.0.1:9999", 1000, "");
    assert (rc == 0);

    mlm_client_t *reader2 = mlm_client_new ();
    assert (reader2);
    rc = mlm_client_set_plain_auth (reader2, "reader", "secret");
    assert (rc == 0);
    rc = mlm_client_connect (reader2, "tcp://127.0.0.1:9999", 1000, "");
    assert (rc == 0);

    mlm_client_set_producer (writer1, "weather");
    mlm_client_set_producer (writer2, "traffic");
    mlm_client_set_consumer (reader1, "weather", "newyork");
    mlm_client_set_consumer (reader1, "traffic", "newyork");
    mlm_client_set_consumer (reader2, "weather", "newyork");
    mlm_client_set_consumer (reader2, "traffic", "newyork");

    mlm_client_sendx (writer1, "newyork", "8", NULL);

    mlm_client_recvx (reader1, &subject, &content, NULL);
    assert (streq (mlm_client_address (reader1), "weather"));
    assert (streq (subject, "newyork"));
    assert (streq (content, "8"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_recvx (reader2, &subject, &content, NULL);
    assert (streq (mlm_client_address (reader2), "weather"));
    assert (streq (subject, "newyork"));
    assert (streq (content, "8"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_sendx (writer2, "newyork", "85", NULL);

    mlm_client_recvx (reader1, &subject, &content, NULL);
    assert (streq (mlm_client_address (reader1), "traffic"));
    assert (streq (subject, "newyork"));
    assert (streq (content, "85"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_recvx (reader2, &subject, &content, NULL);
    assert (streq (mlm_client_address (reader2), "traffic"));
    assert (streq (subject, "newyork"));
    assert (streq (content, "85"));
    zstr_free (&subject);
    zstr_free (&content);

    mlm_client_destroy (&writer1);
    mlm_client_destroy (&writer2);
    mlm_client_destroy (&reader1);
    mlm_client_destroy (&reader2);

    //  Done, shut down
    zactor_destroy (&auth);
    zactor_destroy (&server);
    //  @end
    printf ("OK\n");
}