在ZeroMQ(ZMQ)中,实现消息订阅和消息发布(Publish-Subscribe发布订阅模式)涉及到两种不同的套接字类型:PUB(发布者)和SUB(订阅者)。发布者发布消息到特定的主题,而订阅者订阅这些主题并接收相应的消息。
下面是一个简单的使用ZeroMQ的C语言示例,展示如何实现消息订阅和消息发布。
发布者(Publisher)
发布者使用ZMQ_PUB套接字类型,它***将消息发布到一个或多个订阅者***。
#include <zmq.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
void *context = zmq_ctx_new();
void *publisher = zmq_socket(context, ZMQ_PUB);
int rc;
// 绑定发布者套接字到TCP端口
rc = zmq_bind(publisher, "tcp://*:5555");
if (rc != 0) {
printf("Error: %s\n", zmq_strerror(errno));
exit(EXIT_FAILURE);
}
// 发送消息到所有订阅者
while (1) {
char *msg = "Hello, World!";
rc = zmq_send(publisher, msg, strlen(msg), 0);
if (rc == -1) {
printf("Error: %s\n", zmq_strerror(errno));
break;
}
sleep(1); // 每秒发送一条消息
}
zmq_close(publisher);
zmq_ctx_destroy(context);
return 0;
}
订阅者(Subscriber)
订阅者使用ZMQ_SUB套接字类型,它订阅发布者发布的消息。
#include <zmq.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
void *context = zmq_ctx_new();
void *subscriber = zmq_socket(context, ZMQ_SUB);
int rc;
// 连接到发布者
rc = zmq_connect(subscriber, "tcp://localhost:5555");
if (rc != 0) {
printf("Error: %s\n", zmq_strerror(errno));
exit(EXIT_FAILURE);
}
// 订阅所有消息(NULL表示所有主题)
rc = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
if (rc != 0) {
printf("Error: %s\n", zmq_strerror(errno));
exit(EXIT_FAILURE);
}
// 接收消息
while (1) {
char buffer[255];
rc = zmq_recv(subscriber, buffer, 254, 0);
if (rc == -1) {
printf("Error: %s\n", zmq_strerror(errno));
break;
}
buffer[rc] = 0;
printf("Reveive Message: %s\n", buffer);
}
zmq_close(subscriber);
zmq_ctx_destroy(context);
return 0;
}
在这个例子中,发布者每秒发送一条"Hello, World!"消息,而订阅者则接收并打印这些消息。
要编译和运行这些程序,请确保您已经安装了ZeroMQ库,并链接了正确的库文件。将zmq.h与libzmq.so放置在代码的同一级目录里。
编译客户端:
g++ -c ./client.cpp -o ./client.o -I ./
g++ ./client.o -L ./ -lzmq -o ./client
编译服务端:
g++ -c ./server.cpp -o ./sercer.o -I ./
g++ ./server.o -L ./ -lzmq -o ./server
运行客户端和服务端(启动不分先后)
./client
./server
应该能在订阅者的终端窗口中看到发布者发送的消息的输出。
Reveive Message: Hello World!
Reveive Message: Hello World!
Reveive Message: Hello World!
Reveive Message: Hello World!
Reveive Message: Hello World!
Reveive Message: Hello World!
Reveive Message: Hello World!
注释:
可以了也可以用zmq_msg_recv与zmq_msg_send代替zmq_recv和zmq_send