Linux下的zmq编译,Linux下使用ZMQ实践“发布-订阅”模型

一、背景

二、相关知识

2.1 ZMQ_PUBZMQ_PUB A socket of type ZMQ_PUB is used by a publisher to distribute data. Messages sent are distributed in a fan out fashion to all connected peers. The zmq_recv(3) function is not implemented for this socket type. When a ZMQ_PUB socket enters the mute state due to having reached the high water mark for a subscriber, then any messages that would be sent to the subscriber in question shall instead be dropped until the mute state ends. The zmq_send() function shall never block for this socket type.

ZMQ_PUB为发布端socket类型,用于消息分发,消息以扇出的方式分发到各个连接端上。该socket类型仅支持zmq_send进行发送,不支持zmq_recv()。注意当订阅者处理速度慢的时候,需要在PUB设置合适的高水位HWM来保证消息不会丢失。

2.2 ZMQ_SUBZMQ_SUB A socket of type ZMQ_SUB is used by a subscriber to subscribe to data distributed by a publisher. Initially a ZMQ_SUB socket is not subscribed to any messages, use the ZMQ_SUBSCRIBE option of zmq_setsockopt(3) to specify which messages to subscribe to. The zmq_send() function is not implemented for this socket type.

2.3 使用方法

使用方法为一个PUB对应多个SUB,如图所示:

1529829290459084.png

三、实现

Publisher代码如下,绑定在127.0.0.1:5443 上进行监听void test_pub(void *ctx, int times) { int ret = 0, ix = 0; char id[16] = {0}; char request[1024]; void *sock = zmq_socket(ctx, ZMQ_PUB); assert(sock); s_set_id_ex(sock, id, sizeof(id)); ret = zmq_bind(sock, "tcp://127.0.0.1:5443"); assert(ret == 0); LOGN("Pub %s start\n", id); for (ix = 0; ix < times; ix++) { snprintf(request, sizeof(request), "Data-%03s-%03d", id, ix); s_send(sock, request); LOGN("Pub %s send: %s\n", id, request); usleep(300 * 1000); } LOGN("Pub %s stop\n", id); zmq_close(sock); }

Subscriber则进行地址连接,进行接收:int test_sub(void *ctx) { int ret = 0, cnt = 0; char id[16] = {0}; char request[1024]; void *sock = zmq_socket(ctx, ZMQ_SUB); assert(sock); s_set_id_ex(sock, id, sizeof(id)); ret = zmq_connect(sock, "tcp://127.0.0.1:5443"); assert(ret == 0); ret = zmq_setsockopt(sock, ZMQ_SUBSCRIBE, "", 0); assert(ret == 0); LOGN("Sub %s start\n", id); while (++cnt) { s_recv(sock, request); LOGN("Sub %s recv: %s\n", id, request); usleep(300 * 1000); } LOGN("Sub %s stop\n", id); zmq_close(sock); }

主函数入口:int main(int argc, char *argv[]) { void *ctx = zmq_ctx_new(); assert(ctx); srandom(time(NULL)); if (argc > 1) { test_pub(ctx, atoi(argv[1])); } else { test_sub(ctx); } zmq_ctx_destroy(ctx); exit(EXIT_SUCCESS); }

开启2个Subscriber、1个Publisher,执行结果:

Subscriber#1、Subscriber#2 先启动后阻塞住,开启Publisher后才收到消息:./pubsub [ 1528395731.593 ]: Sub 0034 start [ 1528395745.306 ]: Sub 0034 recv: Data-00B9-001 [ 1528395745.607 ]: Sub 0034 recv: Data-00B9-002 [ 1528395745.907 ]: Sub 0034 recv: Data-00B9-003 [ 1528395746.209 ]: Sub 0034 recv: Data-00B9-004 [ 1528395746.509 ]: Sub 0034 recv: Data-00B9-005 [ 1528395746.810 ]: Sub 0034 recv: Data-00B9-006 [ 1528395747.111 ]: Sub 0034 recv: Data-00B9-007 [ 1528395747.413 ]: Sub 0034 recv: Data-00B9-008 [ 1528395747.714 ]: Sub 0034 recv: Data-00B9-009./pubsub [ 1528395738.672 ]: Sub 00B7 start [ 1528395745.306 ]: Sub 00B7 recv: Data-00B9-001 [ 1528395745.607 ]: Sub 00B7 recv: Data-00B9-002 [ 1528395745.907 ]: Sub 00B7 recv: Data-00B9-003 [ 1528395746.209 ]: Sub 00B7 recv: Data-00B9-004 [ 1528395746.509 ]: Sub 00B7 recv: Data-00B9-005 [ 1528395746.810 ]: Sub 00B7 recv: Data-00B9-006 [ 1528395747.111 ]: Sub 00B7 recv: Data-00B9-007 [ 1528395747.413 ]: Sub 00B7 recv: Data-00B9-008 [ 1528395747.714 ]: Sub 00B7 recv: Data-00B9-009

Publisher:./pubsub 10 [ 1528395745.004 ]: Pub 00B9 start [ 1528395745.004 ]: Pub 00B9 send: Data-00B9-000 [ 1528395745.306 ]: Pub 00B9 send: Data-00B9-001 [ 1528395745.606 ]: Pub 00B9 send: Data-00B9-002 [ 1528395745.907 ]: Pub 00B9 send: Data-00B9-003 [ 1528395746.208 ]: Pub 00B9 send: Data-00B9-004 [ 1528395746.509 ]: Pub 00B9 send: Data-00B9-005 [ 1528395746.809 ]: Pub 00B9 send: Data-00B9-006 [ 1528395747.111 ]: Pub 00B9 send: Data-00B9-007 [ 1528395747.412 ]: Pub 00B9 send: Data-00B9-008 [ 1528395747.714 ]: Pub 00B9 send: Data-00B9-009 [ 1528395748.014 ]: Pub 00B9 stopnetstat -anpt|grep pubsub tcp 0 0 127.0.0.1:5443 0.0.0.0:* LISTEN 31141/pubsub tcp 0 0 127.0.0.1:36680 127.0.0.1:5443 ESTABLISHED 31074/pubsub tcp 0 0 127.0.0.1:36678 127.0.0.1:5443 ESTABLISHED 31071/pubsub tcp 0 0 127.0.0.1:5443 127.0.0.1:36680 ESTABLISHED 31141/pubsub tcp 0 0 127.0.0.1:5443 127.0.0.1:36678 ESTABLISHED 31141/pubsub期间netstat查看连接状态,发现Publisher启动后,两个Subscriber才建立起socket连接;

四、结论

参考文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值