zeromq发布-订阅模式简单使⽤
zeromq作为⽹络通讯库,是⽀持发布、订阅机制的,但是⼜与MQTT等发布、订阅概念有所不同。
由于ZMQ通讯是基于CS模型的,没有服务程序做中转,也就意味着订阅端作服务端和发布端作服务端是不同的。
如下图所⽰,每个框表⽰⼀个进程,zmq发布、订阅机制有如下性质:
服务程序作发布者 只能跟作订阅者的客户端程序通信,服务程序作订阅者只能跟作发布者的客户端程序通信。
订阅者作客户端,只能跟⼀个作发布者的服务程序通信。发布者作客户端,只能跟⼀个作订阅者的服务程序通信。
上述情况为只建⽴⼀路socket连接的情况,如过⼀个进程监听多个端⼝号,便可既作发布端,⼜做订阅端了。具体组合⽅式就要视不同需求⽽定了。在这就不做详细说明了,有兴趣可以下载ZeroMQ的电⼦书看⼀下,其中讲到了许多经典组合模型,和zeromq各种详细使⽤⽅法。
ZeroMQ云时代极速消息库电⼦书下载:
如下为在Ubuntu上编写的测试代码:雪岭板材
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "zmq.h"
#include "zmq.h"
int main(int argc, char *argv[])
{
if(argc >= 4 && !strcmp("-sub",argv[2])) // 如果是订阅
{
/*************************** 订阅 ***************************/
void *context = zmq_ctx_new();
void *subscriber = zmq_socket(context, ZMQ_SUB);
if(!strcmp("-rver",argv[1])) //作服务端
zmq_bind(subscriber, "tcp://*:12345");
el if(!strcmp("-client",argv[1])) //作客户端
zmq_connect(subscriber, "tcp://localhost:12345");
el
{
printf("Plea add true param:\n"
"For example:\n"
"-rver -sub [topic1] [...]\n"
"-client -sub [topic1] [...]\n"
"-rver -pub [topic] [msg]\n"
"-client -pun [topic] [msg]\n");
return 0;
}
int i=0;
for(i=3; i<argc; i++)
{
zmq_tsockopt(subscriber, ZMQ_SUBSCRIBE, argv[i], strlen(argv[i])); //允许订阅多个频道 printf("Sub topic: %s\n",argv[i]);
}
char topic_name[256]={0}; //⽤于接收订阅的主题名
char payload[1024]={0}; //⽤于接收订阅主题的内容
while(1)
{
memt(topic_name,0,sizeof(topic_name));
memt(payload,0,sizeof(payload));
int size = zmq_recv (subscriber, topic_name, sizeof(topic_name), 0); //接收订阅的主题名称 if (size == -1)
{
printf("recv topic error!!\n");
}
size = zmq_recv (subscriber, payload, sizeof(payload), 0); //接收订阅的消息
if (size == -1)
{
printf("recv payload error!!\n");
}
printf("Topic:%s Msg:%s\n",topic_name, payload);佳能eos60d
}
zmq_clo(subscriber); //退出时调⽤
zmq_ctx_destroy(context);
return 0;
/*************************** End ***************************/
}
el if(argc == 5 && !strcmp("-pub",argv[2])) //如果是发布
{
/*************************** 发布 ***************************/
void *context = zmq_ctx_new();
void *publisher = zmq_socket(context, ZMQ_PUB);
if(!strcmp("-rver",argv[1])) //作服务端
干煸菜花的家常做法
zmq_bind(publisher, "tcp://*:12345");
el if(!strcmp("-client",argv[1])) //作客户端
zmq_connect(publisher, "tcp://localhost:12345");
zmq_connect(publisher, "tcp://localhost:12345");
el
{
printf("Plea add true param:\n"
"For example:\n"
"-rver -sub [topic1] [...]\n"
"-client -sub [topic1] [...]\n"
"-rver -pub [topic] [msg]\n"星吧
"-client -pun [topic] [msg]\n");
return 0;
咖啡功效
}
while(1)
{
zmq_nd (publisher, argv[3], strlen(argv[3]), ZMQ_SNDMORE); //指定要发布消息的主题 zmq_nd (publisher, argv[4], strlen(argv[4]), 0); //向设置的主题发布消息
//zmq_nd (publisher, "hello", strlen("hello"), ZMQ_SNDMORE); //可发布多个主题的消息 //zmq_nd (publisher, "world", strlen("world"), 0);
荷包蛋怎么煮sleep(1); //每秒发布⼀次
}
zmq_clo(publisher); //退出时调⽤
长高的药
zmq_ctx_destroy(context);
return 0;
学习平板/*************************** End ***************************/
}
el
{
printf("Plea add true param:\n"
"For example:\n"
"-rver -sub [topic1] [...]\n"
"-client -sub [topic1] [...]\n"
"-rver -pub [topic] [msg]\n"
"-client -pun [topic] [msg]\n");
return 0;
}
return 0;
}
如下为测试⽅法和测试结果:
订阅者作服务程序:
发布者作服务程序:
MQTT在订阅时⽀持通过 “#“ 符号通配订阅多个主题。⽆意中发现zeromq也是默认⽀持这⼀特性的。
⽐如 要订阅 "hello/123" "hello/456" "hello/789"这⼏个主题,直接订阅"hello/"主题就⾏了。如下为测试结果:
运⾏测试程序订阅主题"123",然后运⾏程序向主题"1234"发布消息,订阅端也能够收到主题为"1234"的消息。