- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试使用 ZMQ与 CPPZMQ C++ 包装器,它似乎是 C++ Bindings 中建议的包装器.
客户端/服务器(REQ/REP)似乎工作正常。当尝试实现一对发布/订阅程序时,第一条消息似乎在订阅者中丢失了。为什么?
发布者.cpp:
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <boost/format.hpp>
#include <zmq.hpp>
#include <string>
#include <iostream>
int main()
{
zmq::context_t context(1);
zmq::socket_t publisher(context, ZMQ_PUB);
publisher.bind("tcp://*:5555");
for(int n = 0; n < 3; n++) {
zmq::message_t env1(1);
memcpy(env1.data(), "A", 1);
std::string msg1_str = (boost::format("Hello-%i") % (n + 1)).str();
zmq::message_t msg1(msg1_str.size());
memcpy(msg1.data(), msg1_str.c_str(), msg1_str.size());
std::cout << "Sending '" << msg1_str << "' on topic A" << std::endl;
publisher.send(env1, ZMQ_SNDMORE);
publisher.send(msg1);
zmq::message_t env2(1);
memcpy(env2.data(), "B", 1);
std::string msg2_str = (boost::format("World-%i") % (n + 1)).str();
zmq::message_t msg2(msg2_str.size());
memcpy(msg2.data(), msg2_str.c_str(), msg2_str.size());
std::cout << "Sending '" << msg2_str << "' on topic B" << std::endl;
publisher.send(env2, ZMQ_SNDMORE);
publisher.send(msg2);
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}
return 0;
}
订阅者.cpp:
#include <zmq.hpp>
#include <string>
#include <iostream>
int main()
{
zmq::context_t context(1);
zmq::socket_t subscriber(context, ZMQ_SUB);
subscriber.connect("tcp://localhost:5555");
subscriber.setsockopt(ZMQ_SUBSCRIBE, "B", 1);
while(true)
{
zmq::message_t env;
subscriber.recv(&env);
std::string env_str = std::string(static_cast<char*>(env.data()), env.size());
std::cout << "Received envelope '" << env_str << "'" << std::endl;
zmq::message_t msg;
subscriber.recv(&msg);
std::string msg_str = std::string(static_cast<char*>(msg.data()), msg.size());
std::cout << "Received '" << msg_str << "'" << std::endl;
}
return 0;
}
程序输出:
$ ./publisher
Sending 'Hello-1' on topic A
Sending 'World-1' on topic B
Sending 'Hello-2' on topic A
Sending 'World-2' on topic B
Sending 'Hello-3' on topic A
Sending 'World-3' on topic B
$ ./subscriber
Received envelope 'B'
Received 'World-2'
Received envelope 'B'
Received 'World-3'
(注意:订阅者在执行发布者之前执行)
奖励问题:顺便问一下,是我的印象还是这个 C++ 包装器级别很低?我看不到对 std::string 的直接支持,传输简单字符串的代码看起来非常冗长。
最佳答案
在 the ZeroMQ Guide 中找到了答案:
There is one more important thing to know about PUB-SUB sockets: you do not know precisely when a subscriber starts to get messages. Even if you start a subscriber, wait a while, and then start the publisher, the subscriber will always miss the first messages that the publisher sends. This is because as the subscriber connects to the publisher (something that takes a small but non-zero time), the publisher may already be sending messages out.
This "slow joiner" symptom hits enough people often enough that we're going to explain it in detail. Remember that ZeroMQ does asynchronous I/O, i.e., in the background. Say you have two nodes doing this, in this order:
Subscriber connects to an endpoint and receives and counts messages. Publisher binds to an endpoint and immediately sends 1,000 messages. Then the subscriber will most likely not receive anything. You'll blink, check that you set a correct filter and try again, and the subscriber will still not receive anything.
Making a TCP connection involves to and from handshaking that takes several milliseconds depending on your network and the number of hops between peers. In that time, ZeroMQ can send many messages. For sake of argument assume it takes 5 msecs to establish a connection, and that same link can handle 1M messages per second. During the 5 msecs that the subscriber is connecting to the publisher, it takes the publisher only 1 msec to send out those 1K messages.
In Chapter 2 - Sockets and Patterns we'll explain how to synchronize a publisher and subscribers so that you don't start to publish data until the subscribers really are connected and ready. There is a simple and stupid way to delay the publisher, which is to sleep. Don't do this in a real application, though, because it is extremely fragile as well as inelegant and slow. Use sleeps to prove to yourself what's happening, and then wait for Chapter 2 - Sockets and Patterns to see how to do this right.
The alternative to synchronization is to simply assume that the published data stream is infinite and has no start and no end. One also assumes that the subscriber doesn't care what transpired before it started up. This is how we built our weather client example.
So the client subscribes to its chosen zip code and collects 100 updates for that zip code. That means about ten million updates from the server, if zip codes are randomly distributed. You can start the client, and then the server, and the client will keep working. You can stop and restart the server as often as you like, and the client will keep working. When the client has collected its hundred updates, it calculates the average, prints it, and exits.
关于c++ - ZeroMQ (cppzmq) 订阅者跳过第一条消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45740168/
我的算法- private static MyList skip$DeleteItem(MyList L , int M , int N){ MyList curr = L; MyLi
我正在 SWI-Prolog 下开发,但我的目标是 Erlog (https://github.com/rvirding/erlog)。我需要一种使用非标准 Prolog 语法的方法。 有没有办法
我正在尝试从应用程序下载一大堆文件。它的shell命令是“下载文件名”。 我有一个文本文件,其中包含必须下载的所有文件名。我要做的就是运行一个脚本/命令,以便在执行上述命令时 1.从文本文件中提取文件
我试图循环遍历所有用户的评论,但使用 if 语句查找特定值。问题是我的应用程序崩溃了,因为一些用户没有发表评论,因此我得到“无法读取‘收集’未定义的属性”。如何跳过 if 语句的未定义值?代码如下:
我们有按年份分区的索引,例如: items-2019 items-2020 考虑以下数据: POST items-2019/_doc { "@timestamp": "2019-01-01" }
我只是编写一个页面来按实体编号查看每个 ASCII 条目,我想知道是否有一种更简单/更干净的方法来跳过不需要的数字。 var x = new Ar
我希望能够普遍使用重复条目,但也能够跳过特定日期。例子: ** TODO swim practice SCHEDULED 但是,我提前知道 2013-12-25 不会有练习。但是,当我将项目标
如何跳过像这样的 for 循环的一次迭代: for (int i = 65; i <= 90; i++) { if (!(i == 73)) { uniq.add((char) i);
这个问题已经存在: Scanner issue when using nextLine after nextXXX [duplicate] 已关闭 9 年前。 ask=1; while(ask==1)
我在使用一个程序时遇到了一些麻烦,我应该允许用户在程序中输入任意数量的数字,直到他们不再想要为止。然后程序应该计算输入数字的平均值和最大值。我哪里做错了? import java.util.Scann
我有一个名为segments的 Sprite 数组,我想在每个循环中跳过segments的第一个元素。我目前正在这样做: var first = true; for each (var segment
我目前正在编写一个 for 循环来遍历包含 38 个元素的 2D。然而,其中一些元素为空,我希望 for 循环简单地跳过它们(因为在我正在解决的难题中,它们没有与它们相关的移动)。快速搜索表明,我可以
我想使用pre-commit处理我的 git 项目的 git hooks。但是,当我使用它时,git commit 命令不断跳过 unittest 执行: (smartexchange) trnboo
这个问题在这里已经有了答案: Does scanf() take '\n' as input leftover from previous scanf()? (1 个回答) 关闭 9 年前。 我正在
我正在迭代 csv 文件中的每一行,并仅选择/计算满足条件的行。但是,当连续出现错误时,它会停止循环。有没有办法告诉 python 跳过错误并移动到下一行?我使用了 try 函数但没有工作。我的代码是
感谢您提供的优秀示例,我试过了,它按我的预期工作。很高兴看到有人了解问题的本质。但是,我认为我应该用 Lift 标记问题,因为我正在使用 Lift 框架,这就是(仍然)发生这个问题的地方(尽管我仍然认
大家好,我正在编写一个算法来从 NodeTree 中删除具体分支(例如 DSF)。如果您选择 Node 的名称,算法将检查该 Node 是否是其他 Node 的父 Node ;如果是,它会获取该 No
附有代码和输出。 基本上它是第二次跳过我的输入。就像我启动代码一样,它让我输入一个选项,然后第二次跳过输入,直接转到开关的默认情况。 然后第三次它就会允许我输入。不明白为什么。 任何帮助将不胜感激。
我在 JavaScript 中有一个 for 循环,它会定期跳过间隔,但我无法确定原因。 console.log(parseInt($('input.num-to-add').val())); num
我正在 JasperSoft 中填写参数。在我的报告中我有参数:参数_1、参数_2、参数_3 int a; for (a = 0; a < headers.length; a++) {
我是一名优秀的程序员,十分优秀!