ZeroMQ C ++中的多个发布者这是一个不错的选择吗?

时间:2017-11-22 13:31:43

标签: c++ zeromq

我是ZeroMQ的新手。我想创建多个发布商,每个发布商都在发布特定数据,例如:

  1. 发布商1:发布图片数据
  2. 发布商2:发布音频数据
  3. 发布商3:发布文本数据
  4. 基本上,我的要求是发布来自多个发布者的数据,并在另一方使用多个接收者接收。

    请参阅以下示例代码:

    data_publisher.cpp

    //  Prepare our context and all publishers
    zmq::context_t context(1);
    zmq::socket_t publisher1(context, ZMQ_PUB);
    zmq::socket_t publisher2(context, ZMQ_PUB);
    zmq::socket_t publisher3(context, ZMQ_PUB);
    zmq::socket_t publisher4(context, ZMQ_PUB);
    
    publisher1.bind("tcp://*:5556");
    publisher2.bind("tcp://*:5557");
    publisher3.bind("tcp://*:5558");
    publisher4.bind("tcp://*:5559");
    
    //  Initialize random number generator
    srandom((unsigned)time(NULL));
    while (1) {
        // sample data
        int zipcode1 = within(100000);
        int zipcode2 = within(100000);
        int zipcode3 = within(100000);
        int zipcode4 = within(100000);
    
        int temperature1 = within(215) - 80;
        int temperature2 = within(215) - 80;
        int temperature3 = within(215) - 80;
        int temperature4 = within(215) - 80;
    
        int relhumidity1 = within(50) + 10;
        int relhumidity2 = within(50) + 10;
        int relhumidity3 = within(50) + 10;
        int relhumidity4 = within(50) + 10;
    
        zmq::message_t message1(20);
        zmq::message_t message2(20);
        zmq::message_t message3(20);
        zmq::message_t message4(20);
    
        snprintf((char*)message1.data(), 20, "%05d %d %d", zipcode1, temperature1, relhumidity1);
        snprintf((char*)message2.data(), 20, "%05d %d %d", zipcode2, temperature2, relhumidity2);
        snprintf((char*)message3.data(), 20, "%05d %d %d", zipcode3, temperature3, relhumidity3);
        snprintf((char*)message4.data(), 20, "%05d %d %d", zipcode4, temperature4, relhumidity4);
    
        publisher1.send(message1);
        publisher2.send(message2);
        publisher3.send(message3);
        publisher4.send(message4);
    }
    

    data_receiver.cpp

    zmq::context_t context(1);
    
    //  Socket to talk to server
    zmq::socket_t subscriber1(context, ZMQ_SUB);
    zmq::socket_t subscriber2(context, ZMQ_SUB);
    zmq::socket_t subscriber3(context, ZMQ_SUB);
    zmq::socket_t subscriber4(context, ZMQ_SUB);
    
    subscriber1.connect("tcp://localhost:5556");
    subscriber2.connect("tcp://localhost:5557");
    subscriber3.connect("tcp://localhost:5558");
    subscriber4.connect("tcp://localhost:5559");
    
    const char* filter = (argc > 1) ? argv[1] : "10001 ";
    subscriber1.setsockopt(ZMQ_SUBSCRIBE, filter, strlen(filter));
    subscriber2.setsockopt(ZMQ_SUBSCRIBE, filter, strlen(filter));
    subscriber3.setsockopt(ZMQ_SUBSCRIBE, filter, strlen(filter));
    subscriber4.setsockopt(ZMQ_SUBSCRIBE, filter, strlen(filter));
    
    //  Process 100 updates
    int update_nbr;
    long total_temp1 = 0;
    long total_temp2 = 0;
    long total_temp3 = 0;
    long total_temp4 = 0;
    
    for (update_nbr = 0; update_nbr < 100; update_nbr++)
    {
        zmq::message_t update1;
        zmq::message_t update2;
        zmq::message_t update3;
        zmq::message_t update4;
        int zipcode1, temperature1, relhumidity1;
        int zipcode2, temperature2, relhumidity2;
        int zipcode3, temperature3, relhumidity3;
        int zipcode4, temperature4, relhumidity4;
    
        subscriber1.recv(&update1);
        subscriber2.recv(&update2);
        subscriber3.recv(&update3);
        subscriber4.recv(&update4);
    
        std::istringstream iss1(static_cast<char*>(update1.data()));
        std::istringstream iss2(static_cast<char*>(update2.data()));
        std::istringstream iss3(static_cast<char*>(update3.data()));
        std::istringstream iss4(static_cast<char*>(update4.data()));
    
        iss1 >> zipcode1 >> temperature1 >> relhumidity1;
        iss2 >> zipcode2 >> temperature2 >> relhumidity2;
        iss3 >> zipcode3 >> temperature3 >> relhumidity3;
        iss4 >> zipcode4 >> temperature4 >> relhumidity4;
    
        total_temp1 += temperature1;
        total_temp2 += temperature2;
        total_temp3 += temperature3;
        total_temp4 += temperature4;
    }
    
    std::cout << "Average temperature for zipcode '" << filter << "' was "
              << (int)(total_temp1 / update_nbr) << "F" << std::endl;
    std::cout << "Average temperature for zipcode '" << filter << "' was "
              << (int)(total_temp2 / update_nbr) << "F" << std::endl;
    std::cout << "Average temperature for zipcode '" << filter << "' was "
              << (int)(total_temp3 / update_nbr) << "F" << std::endl;
    std::cout << "Average temperature for zipcode '" << filter << "' was "
              << (int)(total_temp4 / update_nbr) << "F" << std::endl;
    

    请注意,上面的代码是获取建议/建议的示例代码。

    我想知道它是否是一个不错的选择,如上面的示例代码所示?

1 个答案:

答案 0 :(得分:2)

仍在等待任何数量上的事实,但让我们开始:

ZeroMQ是使用智能启用工具的概念,而低级系统编程则由ZeroMQ核心元素隐藏, Context - 启动。

这就是说,高级工具,形式化为可扩展的正式通信模式原型,提供某种人类模仿行为 - PUB出版商确实&#34;发布&#34;, { {1}} 订阅者可以&#34;订阅&#34;, SUB 请求者可以&#34;请求&#34;, REQ 回复者确实可以回复&#34;等等。

这些具有行为的AccessPoints可以 REP 进入某种分布式行为基础架构,一旦获得一些基本规则。其中一条规则是不要打扰实际的传输类,这些都是功能丰富的技术,目前跨越.bind()/.connect()的景观,低级细节, { inproc:// | ipc:// | tcp:// | pgm:// | epgm:// | vmci:// } < / strong> -instance将处理所有这些 透明地对待你的高级行为。别忘了这个。另一个规则是,您可以确定发送的每封邮件都是无错误传送或者根本没有传送 - 没有任何妥协,没有折磨垃圾邮件传递给傻瓜或使收件人的AccessPoint后处理崩溃。

如果不理解这一点,ZeroMQ并不是最大限度地利用它来为我们提供这种奢华工具所设计的舒适性和强大功能。

回到你的困境:

上面说过几句话并且你的主要架构还不清楚,它仍然可以在这里帮助你。

ZeroMQ摘要,分布式行为Socket-tool主要是纯粹的 Context() schedulling设备。这意味着,与Socket相关联的任何接收AccessPoints [SERIAL]都不会期望任意重新排序纯粹的消息流。

这意味着,在任何情况下,只需&#34;只需&#34; - { .bind() | .connect() } 进程安排或在极端情况下,其中为真 - [CONCURRENT] 流程安排在技术上是精心策划的,单个&#34;纯&#34; - [PARALLEL] 投放渠道不允许[SERIAL] -system继续提供这种流程调度模式,并将事件/处理流程切换为纯粹的&#34; - { [CONCURRENT] | [PARALLEL] } 消息序列。

A)对于引入多个独立运行的ZeroMQ分布式行为Socket实例,确实可能既是原因又必须

B)另一方面,对于全局分布式系统行为一无所知,无人能说清楚,是否进入多个独立操作的Socket实例不仅浪费时间和资源,而且由于极端错误或完全缺失初始工程决策而导致不合理的低于平均水平或不可接受的端到端系统行为表现不佳。

性能?

不要在这个领域猜测,永远不要。而是从第一个定量声明的需求开始,在此基础上技术推理的设计将能够继续并定义资源映射和性能调整所需的所有步骤,直到平台限制。

ZeroMQ在过去的二十年里一直以其卓越的性能特点和设计与设计而闻名。工程团队在完善可扩展性和性能包络方面做了大量工作,同时保持特定程序员无法实现的延迟。确实是ZeroMQ地下室隐藏的一大块系统编程。

&#34; 数据巨大&#34; - 好的,定义尺寸 - 发送 [SERIAL] 消息 1E+9 大小有其他性能调整,而不是提供 1 [B] 大小的1E + 3消息。

&#34; 尽快&#34; - 好的,给定大小定义快速 以及消息的预期节奏1 / s~ 1.000.000 [B] < / strong>,10 / s~ 1 [Hz] ,1000 / s~ 10 [Hz]

当然,在某些情况下,这种要求的混合可能会超出当代计算设备的能力范围。在任何编程开始之前,必须对其进行最佳审核,因为否则您只是破坏了一些事物上的编程工作量,这些事情永远不会飞,所以最好能够充分证明解决方案体系结构的可行性和可行性。可接受的资源和成本周长。

因此,如果您的项目需要某些内容,首先定义并定量指定实际内容,下一步,解决方案架构可以开始对其进行排序并提供决策,工具和哪些工具配置可以匹配定义的目标功能和性能目标水平。

通过提升屋顶开始建造房屋永远不会回答如何布置地下室墙壁的问题,这将是一个足够但没有过度设计的铁混凝土铠装厚度,这将带来未知数量高层建筑地板。已经建造的屋顶很容易出现,但与系统和严格的设计无关。工程实践。