publish-subscribe模式是单向的,pub只能发, sub只能收
如果pub没有任何sub,那么消息将会被丢弃
如果sub消费得比较慢,消息就会堆积在pub端
sub 除了要创建 ZMQ_SUB 类型的socket,并连接之外,还要 调用 zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE,filter, strlen (filter)); 来进行注册,才有效果。 其中filter用来匹配消息开头的字符串,如果匹配则接受下来,否则丢弃;但如果filter = NULL,并且长度为0的话,则表示所有的消息都接收。
c++实例:
server端(作用:广播当前时间)
#define _CRT_SECURE_NO_WARNINGS
#include "zmq.h"
#include "zmq_utils.h"
#include <string.h>
#include <time.h>
#include <assert.h>
#include <iostream>
using namespace std;
int main(void)
{
time_t tt;
//prepare context and socket
void* context = zmq_init(1); //指定zmq处理I/O事件的thread pool为1
void* z_socket = zmq_socket(context, ZMQ_PUB);
//在5555端口打开一个ZMQ套接字,等待请求,收到后应答当前时间
zmq_bind(z_socket, "tcp://*:5555");
while (true)
{
//取的当前时间
tt = time(0);
char Curr_time[32] = { 0 };
strftime(Curr_time, 32, "%Y-%m-%d %H-%M-%S", localtime(&tt));
//加一段中文观察客户端会不会产生乱码
char chinese[32] = "当前时间: ";
char* res = strcat(chinese, Curr_time);
zmq_msg_t send_msg;
zmq_msg_init_size(&send_msg, 64);
memcpy(zmq_msg_data(&send_msg), res, 64);
zmq_sendmsg(z_socket, &send_msg, 0);
zmq_msg_close(&send_msg);
//睡眠3秒,减慢广播消息速度
Sleep(3000);
}
zmq_close(z_socket);
zmq_term(context);
return 0;
}
client端(可启动多个实例查看当前时间)
#define _CRT_SECURE_NO_WARNINGS
#include "zmq.h"
#include "zmq_utils.h"
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
void* context = zmq_init(1);
void* z_socket = zmq_socket(context, ZMQ_SUB);
zmq_setsockopt(z_socket, ZMQ_SUBSCRIBE, NULL, 0); //*important*
zmq_connect(z_socket, "tcp://localhost:5555");
while (true)
{
zmq_msg_t recv_msg;
zmq_msg_init(&recv_msg);
zmq_msg_recv(&recv_msg, z_socket, 0);
cout << "receive the response from server: \t";
cout << (char*)zmq_msg_data(&recv_msg) << endl;
zmq_msg_close(&recv_msg);
}
zmq_close(z_socket);
zmq_term(context);
return 0;
}