当前位置: 首页 > news >正文

zmq发布-订阅模式c++实现

上一篇讲到zmq的安装及简单的请求-应答模式,本篇主要来看一下zmq的pub-sub代码如何实现。

发布-订阅模式的特点:

1.一个发布者可以被多个订阅者订阅,即发布者和订阅者是1:n的关系

2.当发布者数据内容发生变化时发布数据,所有订阅者均能及时收到数据。

发布者的代码:pub.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include "zmq.h"

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

    void* publisher = zmq_socket(context, ZMQ_PUB);
    assert(publisher != NULL);

    int ret = zmq_bind(publisher, "tcp://*:5555");
    assert(ret == 0);

    int i = 0;
    while(1)
    {
        char szBuf[1024] = {0};
        snprintf(szBuf, sizeof(szBuf), "server i=%d", i);
        printf("pub ctx: server i = %d\n",i);
        ret = zmq_send(publisher, szBuf, strlen(szBuf) + 1, 0);
        i++;

        sleep(1);
    }

    zmq_close (publisher);
    zmq_ctx_destroy (context);

    return 0;
}

订阅者的代码:sub.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include "zmq.h"

int main()
{
    printf("Hello sub!\n");

    void* context = zmq_ctx_new();
    assert(context != NULL);

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

    int ret = zmq_connect(subscriber, "tcp://localhost:5555");
    assert(ret == 0);

    ret = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
    assert(ret == 0);

    while(1)
    {
        printf("enter while to sub ctx\n");
        char szBuf[1024] = {0};
        ret = zmq_recv(subscriber, szBuf, sizeof(szBuf) - 1, 0);
        if (ret > 0)
        {
            printf("%s\n", szBuf);
        }
    }

    zmq_close(subscriber);
    zmq_ctx_destroy(context);

    return 0;
}

特别注意:

1.我们在pub中bind,在sub中connect,在zmq的使用中无论是在pub还是sub中都可以bind,但是一般我们在pub中bind,在sub中connect 。反之sub端可能收不到消息

2.zmq_setsockopt – 设置zmq socket属性,sub端必须使用此方法,否则是收不到消息的。详细使用方法见官方文档:http://api.zeromq.org/3-2:zmq-setsockopt

3.pub端不能使用recv函数,sub端不能使用send函数

编译:

g++ -o sub sub.cpp -lzmq
g++ -o pub pub.cpp -lzmq

运行:先运行pub可能会使订阅者错过部分发布内容,要想订阅完整的内容需要先启动sub,我这里启动两个sub

 

相关文章:

  • linux报错:bash: syntax error near unexpected token `(‘ --路径中有括号怎么处理?
  • golang学习总结--函数
  • golang学习总结--结构体、接口
  • 解决运行时报错:error while loading shared libraries xxx.so,cannot open shared object file
  • 超实用:linux shell光标移动常用快捷键
  • git commit之后如何撤销
  • golang学习总结--协程、channel
  • 跟我一起写dockerfile
  • dockerfile中多个FROM指令的意义(multistage)
  • dockerfile实战:使用dockerfile制作c/c++程序docker镜像
  • c++11并发编程一(std::thread之:thread构造函数)
  • c++11并发编程二(std::thread之:线程入口函数)
  • 身份证校验码计算:根据身份证前17位计算第18位校验码-c++实现
  • c++11并发编程三(使用std::future、std::promise获取线程返回值)
  • mysql删除表时报错:Cannot delete or update a parent row: a foreign key constraint fails 解决办法
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 10个最佳ES6特性 ES7与ES8的特性
  • classpath对获取配置文件的影响
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Flannel解读
  • Java|序列化异常StreamCorruptedException的解决方法
  • js中forEach回调同异步问题
  • LeetCode29.两数相除 JavaScript
  • MySQL数据库运维之数据恢复
  • Promise面试题,控制异步流程
  • PV统计优化设计
  • unity如何实现一个固定宽度的orthagraphic相机
  • Vue2 SSR 的优化之旅
  • 半理解系列--Promise的进化史
  • 笨办法学C 练习34:动态数组
  • 翻译:Hystrix - How To Use
  • 利用jquery编写加法运算验证码
  • 前端代码风格自动化系列(二)之Commitlint
  • 前端性能优化——回流与重绘
  • 深入浅出Node.js
  • 实习面试笔记
  • 数据结构java版之冒泡排序及优化
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 新版博客前端前瞻
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (2.2w字)前端单元测试之Jest详解篇
  • (52)只出现一次的数字III
  • (windows2012共享文件夹和防火墙设置
  • (分布式缓存)Redis分片集群
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • .bashrc在哪里,alias妙用
  • .Net FrameWork总结
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • /bin/rm: 参数列表过长"的解决办法
  • [android] 切换界面的通用处理
  • [BUUCTF 2018]Online Tool
  • [C++] cout、wcout无法正常输出中文字符问题的深入调查(1):各种编译器测试