ZeroMQ_06 发布-订阅代理服务

我们经常会需要将发布-订阅模式扩充到不同类型的网络中。比如说,有一组订阅者是在外网上的,我们想用广播的方式发布消息给内网的订阅者,而用TCP协议发送给外网订阅者。

我们要做的就是写一个简单的代理服务装置,在发布者和外网订阅者之间搭起桥梁。这个装置有两个端点,一端连接内网上的发布者,另一端连接到外网上。它会从发布者处接收订阅的消息,并转发给外网上的订阅者们。

server

#include "../zhelpers.h"

int main (void)
{
    //  Prepare our context and publisher
    void *context = zmq_ctx_new ();
    void *publisher = zmq_socket (context, ZMQ_PUB);
    int rc = zmq_bind (publisher, "tcp://*:5557");
    assert (rc == 0);

    //  Initialize random number generator
    srandom ((unsigned) time (NULL));
    while (1) {
        //  Get values that will fool the boss
        int zipcode, temperature, relhumidity;
        zipcode     = randof (100000);
        temperature = randof (215) - 80;
        relhumidity = randof (50) + 10;

        //  Send message to all subscribers
        char update [20];
        sprintf (update, "%05d %d %d", zipcode, temperature, relhumidity);
         printf("send message : %s\n", update);
        s_send (publisher, update);
    }
    zmq_close (publisher);
    zmq_ctx_destroy (context);
    return 0;
}

proxy

#include "../zhelpers.h"

int main (void)
{
    void *context = zmq_ctx_new ();

    //  This is where the weather server sits
    void *frontend = zmq_socket (context, ZMQ_XSUB);
    int rc =zmq_connect (frontend, "tcp://localhost:5557");
    assert (rc == 0);
    //  This is our public endpoint for subscribers
    void *backend = zmq_socket (context, ZMQ_XPUB);
   rc = zmq_bind (backend, "tcp://127.0.0.1:8111");
   assert (rc == 0);

    //  Run the proxy until the user interrupts us
    printf("zmq_proxy...begin \n");
    zmq_proxy (frontend, backend, NULL);
    printf("zmq_proxy...end \n");
    zmq_close (frontend);
    zmq_close (backend);
    zmq_ctx_destroy (context);
    return 0;
}

client

#include "../zhelpers.h"

int main (int argc, char *argv [])
{
    //  Socket to talk to server
    printf ("Collecting updates from weather server...\n");
    void *context = zmq_ctx_new ();
    void *subscriber = zmq_socket (context, ZMQ_SUB);
    int rc = zmq_connect (subscriber, "tcp://localhost:8111");
    assert (rc == 0);

    //  Subscribe to zipcode, default is NYC, 10001
    const char *filter = "1";
    rc = zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE,
                         filter, strlen (filter));
    assert (rc == 0);

    //  Process 100 updates
    int update_nbr;
    long total_temp = 0;
    for (update_nbr = 0; update_nbr < 100; update_nbr++) {
        char *string = s_recv (subscriber);
        printf("recv message : %s\n", string);
        int zipcode, temperature, relhumidity;
        sscanf (string, "%d %d %d",
            &zipcode, &temperature, &relhumidity);
        total_temp += temperature;
        free (string);
    }
    printf ("Average temperature for zipcode '%s' was %dF\n",
        filter, (int) (total_temp / update_nbr));

    zmq_close (subscriber);
    zmq_ctx_destroy (context);
    return 0;
}

我们称这个装置为代理,因为它既是订阅者,又是发布者。这就意味着,添加该装置时不需要更改其他程序的代码,只需让外网订阅者知道新的网络地址即可。

 

 out

// server
send message : 69513 126 18
send message : 81998 2 52
send message : 89759 55 11
send message : 46156 21 21
send message : 99744 -27 59
send message : 03687 56 26
send message : 87373 -9 39
send message : 03237 -42 29
send message : 81249 119 17
send message : 13946 -23 58
send message : 11892 126 56
send message : 28408 88 25
send message : 13726 66 57
send message : 15999 -50 30
send message : 39683 -51 43
send message : 38166 -43 25
send message : 71268 -70 41
send message : 29271 -63 50

// client
recv message : 10623 -4 22
recv message : 17512 82 27
recv message : 16574 -75 39
recv message : 12919 -31 39
recv message : 19449 93 45
recv message : 16524 19 23
recv message : 15305 63 54
recv message : 10077 -49 37
recv message : 14690 -1 22
Average temperature for zipcode '1' was 17F

 

posted @ 2020-05-07 09:13  Vzf  阅读(563)  评论(0编辑  收藏  举报