ZMQ(二、发布订阅模型)

ZMQ(PUB-SUB)

服务端不管客户端这边有没有接收到数据,只负责发送。客户端不能发送数据,只负责接收。

(1)一个发布者,多个订阅者的关系,1:n;

(2)只有设置了与服务端发送消息相同订阅类型的客户端才能接收到消息

(3)服务端可以绑定多个端口

注:使用SUB设置一个订阅时,使用zmq_setsockopt()对消息进行过滤

                                                     

 

C++示例代码:

服务端:

//server

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<zmq.h>
#include<assert.h>

using namespace std;


int main()
{
	void *context = zmq_ctx_new();
	void *socket = zmq_socket(context,ZMQ_PUB);
	int ret = zmq_bind(socket, "tcp://*:6666");
	assert(ret == 0);
	ret = zmq_bind(socket, "tcp://*:5555");  //绑定另一个端口5555
	assert(ret == 0);
	
	int i = 0;  //消息计数器
	while (1)
	{
		Sleep(10);
		char sendBuf[1024] = {0};
		sprintf(sendBuf, "[Server] : server = %d", i++);
		int sentBytes = zmq_send(socket, sendBuf, strlen(sendBuf), 0);
		if (sentBytes > 0)
		{
			printf("%s\n", sendBuf);
		}
	}

	zmq_close(socket);
	zmq_ctx_destroy(context);

	system("pause");
	return 0;
}

 

客户端1:(接收6666端口消息)

//客户端1:接收服务端 6666端口的消息

#include<iostream>
#include<thread>
#include<zmq.h>
#include<assert.h>
using namespace std;

void Recv1(void *arg);  //客户端接收线程1
void Recv2(void *arg);  //客户端接收线程2

int main()
{
	void *context = zmq_ctx_new();
	assert(context != NULL);

	void *socket = zmq_socket(context,ZMQ_SUB);
	assert(socket != NULL);

	int ret = zmq_connect(socket, "tcp://localhost:6666");
	assert(ret == 0);

	ret = zmq_setsockopt(socket, ZMQ_SUBSCRIBE, "[Server]", 8);
	assert(ret == 0);

	thread th1(Recv1,socket);
	thread th2(Recv2,socket);

	th1.join();
	th2.join();

	zmq_close(socket);
	zmq_ctx_destroy(context);

	system("pause");
	return 0;
}

void Recv1(void *arg)  //客户端接收线程1
{
	void *socket = arg;

	while(1)
	{
		char recvBuf[1024] = { 0 };
		Sleep(1);
		int recvBytes = zmq_recv(socket, recvBuf, sizeof(recvBuf)-1, 0);
		if (recvBytes > 0)
		{
			printf("[Client] : Recv1--------------:%s\n", recvBuf);
		}
	}
}
void Recv2(void *arg)  //客户端接收线程2
{
	void *socket = arg;

	while (1)
	{
		char recvBuf[1024] = { 0 };
		Sleep(1);
		int recvBytes = zmq_recv(socket, recvBuf, sizeof(recvBuf)-1, 0);
		if (recvBytes > 0)
		{
			printf("[Client] : Recv2--------------:%s\n", recvBuf);
		}
	}
}

客户端2:接收5555端口消息

//客户端2:接收5555端口

#include<iostream>
#include<thread>
#include<zmq.h>
#include<assert.h>
using namespace std;

void Recv3(void *arg);  //客户端接收线程3

int main()
{
	void *context = zmq_ctx_new();
	void *socket = zmq_socket(context, ZMQ_SUB);
	int ret = zmq_connect(socket, "tcp://localhost:5555");
	assert(ret == 0);

	thread th3(Recv3, socket);

	th3.join();

	zmq_close(socket);
	zmq_ctx_destroy(context);
	system("pause");
	return 0;
}


void Recv3(void *arg)  //客户端接收线程3
{
	void *socket = arg;
	int ret = zmq_setsockopt(socket, ZMQ_SUBSCRIBE, "", 0);
	assert(ret == 0);

	while (1)
	{
		char recvBuf[1024] = { 0 };
		Sleep(1);
		int recvBytes = zmq_recv(socket, recvBuf, sizeof(recvBuf)-1, 0);
		if (recvBytes > 0)
		{
			printf("[Client] : Recv3--------------:%s\n", recvBuf);
		}
	}
}

测试结果:

先运行两个客户端,再运行服务端,两个客户端如果设置的过滤一致,那它们接收到的消息应该相同;

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ZMQ是一个高效的消息传递库,支持多种传输协议,包括TCP、UDP、inproc等。它的广泛应用领域包括分布式系统、高性能计算、实时数据处理等。 ZMQ提供了多种通信模式,其中发布订阅模式是其中之一,用于多个订阅者同时订阅同一个主题的消息。下面是使用ZMQ实现发布订阅模式的Python代码示例。 首先,需要安装ZMQ库。可以使用pip命令进行安装: ``` pip install pyzmq ``` 然后,在发布者端,需要创建一个ZMQ的上下文对象,用于创建socket。然后,创建一个PUB类型的socket,并绑定到指定的地址和端口: ```python import zmq context = zmq.Context() socket = context.socket(zmq.PUB) socket.bind("tcp://*:5555") ``` 在订阅者端,也需要创建一个ZMQ的上下文对象,用于创建socket。然后,创建一个SUB类型的socket,并连接到发布者的地址和端口: ```python import zmq context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect("tcp://localhost:5555") ``` 订阅者还需要指定要订阅的主题,可以使用socket的subscribe方法来实现: ```python topic = "news" socket.subscribe(topic.encode()) ``` 发布者可以使用socket的send方法来发送消息,并指定消息的主题: ```python topic = "news" message = "latest news" socket.send_multipart([topic.encode(), message.encode()]) ``` 订阅者可以使用socket的recv方法来接收消息: ```python message = socket.recv_multipart() topic = message[0].decode() content = message[1].decode() print(f"Received message: {content} under topic {topic}") ``` 完整的示例代码如下: Publisher: ```python import zmq context = zmq.Context() socket = context.socket(zmq.PUB) socket.bind("tcp://*:5555") while True: topic = input("Enter topic: ") message = input("Enter message: ") socket.send_multipart([topic.encode(), message.encode()]) ``` Subscriber: ```python import zmq context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect("tcp://localhost:5555") topic = input("Enter topic to subscribe: ") socket.subscribe(topic.encode()) while True: message = socket.recv_multipart() topic = message[0].decode() content = message[1].decode() print(f"Received message: {content} under topic {topic}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值