ZMQ发布订阅模式二次封装

ZeroMQ

参考ZMQ从入门到掌握一
ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字。ZeroMQ 并不是一个对 socket 的封装,不能用它去实现已有的网络协议。它有自己的模式,不同于更底层的点对点通讯模式。它有比 tcp 协议更高一级的协议。(当然 ZeroMQ 不一定基于 TCP 协议,它也可以用于进程间和进程内通讯)它改变了通讯都基于一对一的连接这个假设。ZeroMQ 把通讯的需求看成四类。其中一类是一对一结对通讯,用来支持传统的 TCP socket 模型,但并不推荐使用。常用的通讯模式只有三类:

  • 请求回应模型:由请求端发起请求,并且等待回应端回应请求。从请求端来看,一定是一对对收发配对的;反之,在回应端一定是发收对。请求端和回应端都可以是 1:N 的模型。通常把 1 认为是 server ,N 认为是 Client 。ZeroMQ 可以很好的支持路由功能(实现路由功能的组件叫作 Device),把 1:N 扩展为 N:M (只需要加入若干路由节点)。从这个模型看,更底层的端点地址是对上层隐藏的。每个请求都隐含有回应地址,而应用则不关心它。
  • 发布订阅:这个模型里,发布端是单向只发送数据的,且不关心是否把全部的信息都发送给订阅端。如果发布端开始发布信息的时候,订阅端尚未连接上来,这些信息直接丢弃。不过一旦订阅端连接上来,中间会保证没有信息丢失。同样,订阅端则只负责接收,而不能反馈。如果发布端和订阅端需要交互(比如要确认订阅者是否已经连接上),则使用额外的 socket 采用请求回应模型满足这个需求。
  • 管道模式:单向的

发布者

  • ZmqSendUtil.h
#ifndef ZMQSENDUTIL_H
#define ZMQSENDUTIL_H#include <string>
#include <cpp/zmq.hpp>
class ZmqSendUtil{
private:void *context;void *publisher;std::string url;public:ZmqSendUtil();                              //默认构造方法ZmqSendUtil(void *context, void *publisher, const std::string &url);    //初始化构造方法virtual ~ZmqSendUtil();                     //析构函数int sendMsg(const std::string& info);       //发送消息
};#endif
  • ZmqSendUtil.cpp

#include "ZmqSendUtil.h"
ZmqSendUtil::ZmqSendUtil() {}
ZmqSendUtil::ZmqSendUtil(void *context, void *publisher, const std::string &url) :context(context),publisher(publisher), url(url){//初始化上下文if (this->context == nullptr){this->context = zmq_ctx_new();assert(this->context != nullptr);}//获取socket对象if (this->publisher == nullptr){this->publisher = zmq_socket(this->context, ZMQ_PUB);assert(this->publisher != nullptr);}//socket绑定通信地址int result = zmq_bind(this->publisher, this->url.c_str());assert(result == 0);
}ZmqSendUtil::~ZmqSendUtil() {zmq_close(this->publisher);zmq_ctx_destroy(this->context);
}int ZmqSendUtil::sendMsg(const std::string& info) {int result=-1;if (this->context != nullptr && this->publisher != nullptr){result = zmq_send(this->publisher, info.c_str(), info.length(), 0);return result > 0;}
}

订阅者

  • ZmqRecvUtil.h
#ifndef USV_ZMQRECVUTIL_H
#define USV_ZMQRECVUTIL_H#include <string>
#include <cpp/zmq.hpp>
class ZmqRecvUtil{
private:void *context;void *subscriber;std::string url;public:ZmqRecvUtil();              //默认构造方法ZmqRecvUtil(void *context, void *subscriber, const std::string &url);   //初始化构造方法virtual ~ZmqRecvUtil();     //析构函数std::string recvMsg();      //接收消息
};#endif
  • ZmqRecvUtil.cpp
#include "ZmqRecvUtil.h"
#define MAX_INFO_SIZE 1024ZmqRecvUtil::ZmqRecvUtil() {}ZmqRecvUtil::ZmqRecvUtil(void *context, void *subscriber, const std::string &url) :context(context),subscriber(subscriber),url(url){//初始化上下文contextif (this->context == nullptr){this->context = zmq_ctx_new();  //如果上下文是空的,那么就初始化上下文assert(this->context != nullptr);}//获取socket对象if (this->subscriber == nullptr){   //模式为订阅发布模式 发布端单向发布数据也不管订阅端是否能接收...this->subscriber = zmq_socket(this->context, ZMQ_SUB); //如果订阅者是空的句柄那就创建一个不透明的套接字...assert(this->subscriber != nullptr);}//socket绑定通信地址  绑定特定的ip和端口号获取数据....int result = zmq_connect(this->subscriber, this->url.c_str());assert(result == 0);result = zmq_setsockopt(this->subscriber, ZMQ_SUBSCRIBE, "", 0);assert(result == 0);
}ZmqRecvUtil::~ZmqRecvUtil() {zmq_close(this->subscriber);zmq_ctx_destroy(this->context);
}std::string ZmqRecvUtil::recvMsg() {//读取消息char infoBuffer[MAX_INFO_SIZE] = {0};int ret = zmq_recv(this->subscriber, infoBuffer, MAX_INFO_SIZE , 0);assert(ret != -1);std::string tmp="";                     //返回值不能使用infoBuffer强化类型转换,要重新构建字符串for (int i = 0; i < ret; ++i) {tmp+=infoBuffer[i];}return tmp;
}

测试

  • main.cpp
#include"ZmqSendUtil.h"
#include"ZmqRecvUtil.h"
#include <iostream>
#include <thread>
using namespace std;ZmqSendUtil* publisher = new ZmqSendUtil(nullptr,nullptr,"tcp://127.0.0.1:6666");
ZmqRecvUtil* subscriber = new ZmqRecvUtil(nullptr,nullptr,"tcp://127.0.0.1:6666");// zmq的发送线程函数
void zmq_send_thread() {int cnt = 0;while(true){cnt++;string msg = "hello world " + to_string(cnt);publisher->sendMsg(msg);cout << "send msg: " << msg << endl;Sleep(1000); }
}
// zmq的接收线程函数
void zmq_recv_thread() {while (true) {string msg = subscriber->recvMsg();cout << "recv msg: " << msg << endl;}
}int main(int argc, char const *argv[])
{cout<<"Hello world"<<endl;thread zmq_send(zmq_send_thread);thread zmq_recv(zmq_recv_thread);zmq_send.join();zmq_recv.join();return 0;
}

cmakelist.txt编写

# 版本和项目名称
cmake_minimum_required(VERSION 3.20)
project(example1)
# 设定编译标准为C++11
# 设定头文件路径和动态库路径
set(CXX_STANDARD 11)
set(ZEROMQ_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/zeromq425/include)
set(ZEROMQ_LIBRARY_DIRS ${CMAKE_SOURCE_DIR}/zeromq425/bin/Debug/v140/dynamic)
set(ZEROMQ_LIB libzmq.lib)
include_directories(${ZEROMQ_INCLUDE_DIRS})
link_directories(${ZEROMQ_LIBRARY_DIRS})
# 生成可执行文件并连接到库文件
aux_source_directory(. SRC_DIR)
add_executable(zmqtest ${SRC_DIR})
target_link_libraries(zmqtest libzmq.lib)

结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/28342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《论文阅读》通过生成会话模型的迁移学习会话中的情感识别

《论文阅读》通过生成会话模型的迁移学习会话中的情感识别 前言简介模型结构Source TaskTarget Task损失函数前言 你是否也对于理解论文存在困惑? 你是否也像我之前搜索论文解读,得到只是中文翻译的解读后感到失望? 小白如何从零读懂论文?和我一起来探索吧! 今天为大家…

Qt6之QListWidget——Qt仿ToDesk侧边栏(1)

一、 QLitWidget概述 注意&#xff1a;本文不是简单翻译Qt文档或者接口函数&#xff0c;而侧重于无代码Qt设计器下演示使用。 QListWidget也称列表框类&#xff0c;它提供了一个类似于QListView提供的列表视图&#xff0c;但是它具有一个用于添加和删除项的经典的基于项的接口…

JavaScript算法【入门】

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于海外某世界知名高校就读计算机相关专业。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。…

Jmeter(四) - 从入门到精通 - 创建网络测试计划(详解教程)

1.简介 在本节中&#xff0c;您将学习如何创建基本的 测试计划来测试网站。您将创建五个用户&#xff0c;这些用户将请求发送到JMeter网站上的两个页面。另外&#xff0c;您将告诉用户两次运行测试。因此&#xff0c;请求总数为&#xff08;5个用户&#xff09;x&#xff08;2…

[保研/考研机试] 约瑟夫问题No.2 C++实现

题目要求&#xff1a; 输入、输出样例&#xff1a; 源代码&#xff1a; #include<iostream> #include<queue> #include<vector> using namespace std;//例题5.2 约瑟夫问题No.2 int main() {int n, p, m;while (cin >> n >> p >> m) {//如…

Whisper.cpp 编译使用

Whisper.cpp 编译使用 whisper.cpp 是牛人 ggerganov 对 openai 的 whisper 语音识别模型用 C 重新实现的项目&#xff0c;开源在 github 上&#xff0c;具有轻量、性能高&#xff0c;实用性强等特点。这篇文章主要记录在 windows 平台&#xff0c;如何使用该模型在本地端进行…

docker安装MinIO

简介 Minio 是一个面向对象的简单高性能存储服务。使用 Go 语言编写&#xff0c;性能高、具有跨平台性。 Minio 官网为&#xff1a;https://min.io &#xff0c;有一个中文站点&#xff0c;单内容更新不是很及时&#xff0c;建议从原始官网学习。 本文采用 Docker 安装&…

vscode自动添加注释说明

1. 安装vscode 双击安装程序,默认安装即可(如:VSCodeSetup-x64-1.70.2.exe) 2. 安装doxygen文档生成插件 1> 打开vscode软件,点击左侧插件管理菜单 2> 点击右上角’…‘按钮,选择’Install from VSIX’(联网状态可以直接搜索doxygen下载安装) 3> 选择doxygen离线安装…

【深度学习】【风格迁移】Zero-shot Image-to-Image Translation

论文&#xff1a;https://arxiv.org/abs/2302.03027 代码&#xff1a;https://github.com/pix2pixzero/pix2pix-zero/tree/main 文章目录 Abstract1. Introduction相关工作3. Method Abstract 大规模文本到图像生成模型展示了它们合成多样且高质量图像的显著能力。然而&#x…

Linux项目部署

目录 一JAVAWeb环境的部署【安装JDK&#xff0c;MySQL数据库&#xff0c;Tomcat】 二.手工部署SpringBoot项目&#xff08;写的最好的&#xff09; 1.在IDEA中开发SpringBoot项目并打成jar包--点击右侧的Maven执行package命令 2.将jar包上传到Linux服务器 3.执行以下命令&a…

mysql的高级查询语句

目录 一、本文前言 二、高效查询方式 1&#xff09;指定指字段进行查看 2&#xff09;对字段进行去重查看 3&#xff09;where条件查询 4&#xff09;and 和 or 进行逻辑关系的增加 5&#xff09;查询取值列表中的数据 6&#xff09;between的引用 7&#xff09;like…

NAT及其实验(eNSP,细致易懂)

目录 NAT产生背景 NAT概述NAT&#xff08;Network Address Translation&#xff09;&#xff0c;网络地址转换 NAT工作规则 标准NAT技术 NAPT[网络地址端口转换[Port-->传输层-端口编号]] Easy IP——最简单的PAT NAT Server 静态NAT实验 动态NAT实验 NAPT实验 N…

Redis基础 (三十八)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 1.1 NoSQL 1.2 Redis 二、安装 2.1 安装方式 &#xff1a; 三、目录结构 3.1 rpm -ql redis 3.2 /etc/redis.conf 主配置文件 3.3 /var/lib/redis …

【BMC】OpenBMC开发基础2:修改原有程序

修改原有程序 通常情况下我们会需要修改OpenBMC原有的程序来适配我们的项目&#xff0c;本节将介绍一般的流程。 为此首先我们需要了解devtool这个工具&#xff0c;注意它不是前端开发用的那个devtool&#xff0c;而是由OE&#xff08;或者Yocto&#xff1f;&#xff09;提供…

Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载

上拉、下拉的效果图如下&#xff1a; 使用步骤 1、在清单文件中添加依赖 implementation ‘com.android.support:recyclerview-v7:27.1.1’ implementation “androidx.swiperefreshlayout:swiperefreshlayout:1.0.0” 2、main布局 <LinearLayout xmlns:android"http…

Codeforces Round 891 (Div. 3)

Array ColoringArray Coloring 题目大意 题目要求判断是否可以将数组元素分为两种颜色&#xff0c;使得两种颜色元素的和具有相同的奇偶性&#xff0c;并且每种颜色至少有一个元素被着色。 思路分析 可以通过统计数组中奇数和偶数的个数来判断是否满足条件。分析可知&#x…

适用HarmonyOS 3.1版本及以上的应用及服务开发工具 DevEco Studio 3.1.1 Release 安装

文章目录 安装步骤1.下载安装包2.安装成功后&#xff0c;初次运行studio2.1 配置node与ohpm的环境2.2安装sdk2.3等待安装结束 3.创建项目3.1 点击Create Project3.2 选择一个空项目3.3 项目配置3.4 Finish、等待依赖下载完毕3.5 项目创建完成 tip 提示4.配置运行环境4.1 真机运…

信号平滑或移动平均滤波研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

springboot人事管理系统设计与实现

126springboot人事管理系统java web员工信息管理系统 人事管理系统&#xff0c;属于ERP的一个部分。它单指汇集成功企业先进的人力资源管理理念、人力资源管理实践、人力资源信息化系统建设的经验&#xff0c;以信息技术实现对企业人力资源信息的高度集成化管理&#xff0c;为…

ppt压缩文件怎么压缩最小?文件压缩技巧分享

在日常的工作和学习中&#xff0c;难免会遇到PPT太大&#xff0c;需要将其压缩变小的情况&#xff0c;但很多朋友还不知道怎么压缩PPT文件&#xff0c;下面就给大家分享几个简单的方法&#xff0c;分分钟缩小过大的PPT文件。 一、PowerPoint PowerPoint就是微软公司的演示文稿…