ZeroMQ:我想要发布–;订阅删除旧邮件以支持更新邮件

ZeroMQ:我想要发布–;订阅删除旧邮件以支持更新邮件,zeromq,publish-subscribe,Zeromq,Publish Subscribe,我使用ZeroMQ发布-订阅套接字连接两个进程。发布过程是一个传感器,刷新速度比订阅过程快得多。我希望订阅过程只使用队列中最新的消息,而完全忽略较旧的消息 我曾尝试在订户上设置一个高水位线,但这似乎会删除较新的消息,而不是较旧的消息 有没有一种发布-订阅模式可以让我达到这个目的?好的,我找到了一个解决方案,但我不知道它是否是最好的,所以我现在还不认为它是正确的 zmq::message_t message; int events = 0; size_t events_size = sizeof(

我使用ZeroMQ发布-订阅套接字连接两个进程。发布过程是一个传感器,刷新速度比订阅过程快得多。我希望订阅过程只使用队列中最新的消息,而完全忽略较旧的消息

我曾尝试在订户上设置一个高水位线,但这似乎会删除较新的消息,而不是较旧的消息


有没有一种发布-订阅模式可以让我达到这个目的?

好的,我找到了一个解决方案,但我不知道它是否是最好的,所以我现在还不认为它是正确的

zmq::message_t message;
int events = 0;
size_t events_size = sizeof(int);

// Priming read
subscriber.recv(&message);

// See if there are more messages to read
subscriber.getsockopt(ZMQ_EVENTS, static_cast<void*>(&events), &events_size);
while (events & ZMQ_POLLIN) {

  // Receive the new (and perhaps most recent) message
  subscriber.recv(&message);

  // Poll again for additional messages
  subscriber.getsockopt(ZMQ_EVENTS, static_cast<void*>(&events), &events_size);
}

// Now, message points to the most recent received data.
zmq::message\u t message;
int事件=0;
大小事件大小=sizeof(int);
//启动读取
subscriber.recv(&message);
//查看是否有更多消息要阅读
getsockopt(ZMQ_事件、静态_转换(&EVENTS)和事件大小);
while(events&ZMQ_POLLIN){
//接收新的(可能是最新的)消息
subscriber.recv(&message);
//再次轮询以获取其他消息
getsockopt(ZMQ_事件、静态_转换(&EVENTS)和事件大小);
}
//现在,消息指向最近接收到的数据。
此策略还有一个额外的优点,即队列不应被填满。缺点是我的发布者发送的速度可能会比订阅服务器中的循环运行的速度快,然后它将无限期地循环


这似乎不太可能,但我想让它变得不可能。我还不太确定如何实现这一目标。

从中了解conflate功能(这是一种新功能),我认为它正是您想要的

从文件中:

ZMQ_CONFLATE:只保留最后一条消息 如果设置,插座应仅保持 入站/出站队列中的一条消息,此消息是最后一条消息 已收到消息/要发送的最后一条消息。忽略“ZMQ_RCVHWM”和 “ZMQ_SNDHWM”选项。在中不支持多部分消息 特别是,套接字内部队列中只保留它的一部分


这是一个不可能的情况,因为订阅者永远不可能知道它接收的消息将在发送新消息之前被处理,如果它的速度不够快,无法跟上,那么你就被卡住了。处理这种情况的唯一方法是使用多个订阅者,这些订阅者总共有足够的带宽来处理来自发布者的最大输出。不要使用pub-sub,而是使用dealer router,这样您就可以在所有客户端之间循环消息,并且只需计算出在后端应该替换哪个消息。凌乱的Conflate(如果可用)更好。有关Conflate的详细信息,请参阅其他答案。太好了,谢谢。现在,我们可以删除评论以保持整洁。在筛选传入消息时,重复的问题和有用的答案: