如何使用Java在ZMQ中接收多部分消息?

问题描述

就好像该操作一样简单,我找不到任何有关如何使用ZMQ(Jeromq)接收多部分消息的文档。我检查了指南,但是它仅包含带有此信息的C代码,并且无论我收到哪种消息,似乎我都应该以相同的方式接收消息。

实际上,发生的情况是,我用以下代码在两条消息中收到了多部分消息:

while (running.get()) {
    items.poll();
    if (items.pollin(0)) {
        ByteArray message = receiver.recv(0);
        System.out.println("Received " + String(message,Charset.forName("UTF-8")));
    }
}

如果我发送这样的多部分消息,则“已接收”部分将被打印两次:

publisher.sendMore(message.key);
publisher.send(objectMapper.writeValueAsstring(message.data));

我在做什么错了?

编辑:我知道示例下方有一个语言选择器,但是在仅用C代码内联解释的所有示例中都没有这个特定问题。

修改

我尝试探索API,并找到了hasReceiveMore()方法。我尝试使用它,但是没有用,我最终陷入了这段代码的无限循环:

List<String> parts = new ArrayList<>();
while(receiver.hasReceiveMore()) {
    parts.add(receiver.recvstr());
}

解决方法

Q “我在做什么错了?”

您的代码必须积极地假设每条消息都可能是由多部分消息组成的(此处为零保修,先验程度较小),并积极检查 ZMQ_RECVMORE是否存在标志,在随后的每个.recv()方法调用之后,直到.getsockopt( ZMQ_RECVMORE )方法表示相反为止。

JeroMQ可能已经将此发布的本机API转换为其他一些通用方法,因此最好重新阅读JeroMQ源代码以查找该本机API多部分消息处理(“协议”)包装在JeroMQ-中的位置工具。

EPILOGUE: Verba docent,Exempla trahunt ...

已经帮助了超过130万社区成员和无数匿名站点访问者,因提供帮助而受到惩罚和审查。

删除评论的检查仍在继续。 StackOverflow的精神转向数字极权主义。删除,删除和惩罚那些不断思考并向寻求帮助的人提供帮助和建议的人...
------------------- ------------------
让我们回顾一下事实:
-----
“我不能找不到有关如何接收零件的任何文档,但我尝试了一些类似您提到的内容的方法……也无济于事。Adam Arold 20 hours ago

是我的错还是遗漏了?找不到“任何文档”还是“不起作用”(另一个未发布,可复制的MCVE)?是吗?

(我对这些虚假声明的回答在发布后几分钟内被行政删除...不言自明)
-----
不是答案,也不包含解决方案,我不确定您为什么会感到惊讶,您引用的是与JeroMQ API无关的C API。最后,解决方案是在尝试检查recv标志之前,请先将其移至RECVMORE。这不是您的答案。或者ZMsg可以使用。Adam Arold 11 hours ago


对索赔的分析:

句子#1。 :

“这不是答案,它不包含解决方案。”

IS 是一个答案,尽管有“声明”。它包含一些重要的信息,否则她/他/任何人都将不得不尝试花费数小时(几天或几周?)来进行后续研究,并在概念上很好地理解架构方面的知识,从而避免编写任何格式错误的代码,设计或基本上陷于自己的,错误的决定中,如果没有得到建议和警告,我在过去的13多年与神话般的Martin在一起时遇到的个人缺点(并帮助其他人不再重复)自从v2.1 +起,Sustrik的杰作-ZeroMQ。因此,这种“主张”既是错误的,也没有事实依据。一个轻微的“答案”是荒谬的,答案没有包含解决方案,这是荒谬的,StackOverflow社区成员既不是员工也不愿意大喊大叫,我们对编写满足所有需求(未发布)的代码的承诺越少用例。

句子#2:

(一种表达的感觉)
-而不是被跳过,因为它更多是侮辱而不是公平的情况参数,不是吗?


句子#3:

”“您引用的是与C无关的C API使用JeroMQ API。“

哦,可以肯定,,C API(以及“强制在线”上的ZeroMQ-RFC文档“任何对等实现都必须遵守的协议属性...)是所有这些内容的出发点和主要参考。 ,已发布的ZeroMQ RFC文档和API都是坚实的参考,任何人都可以从这里开始,以便最好地了解内部引擎和所有强制性的“有线线路”服从协议泵的属性正在运行(并且必须正在运行),以便声明自己保持ZeroMQ兼容性。 JeroMQ作者基于这些记录的属性进行工作,不是吗?如果他们没有这样做,或者如果他们“偷工减料”,那故事就丢了,不是我的错,他们没有满足和/或满足所有ZMTP / ZeroMQ-RFC / API属性和要求,是吗?就是说,任何包装器/绑定,包括任何版本的JeroMQ,都还必须遵守这些内部工作规则,这些规则应充分记录在案,并在JeroMQ源代码中进行了证明(如果没有其他地方,则应予以证明)(警告也是提供的答案,不是吗?),如果它想成为与ZeroMQ兼容的工具。同样,如果您当前(使用过的)JeroMQ实现错过了要使用并通读的有据可查的JeroMQ-API文档,(查找说明和示例 >用例代码),该用例声称它没有或寻求和发现任何此类(源代码)信息的意愿,不是共同体赞助者因缺乏前者而受到惩罚,

句子4. + 5.:

需要突出显示:

“在最终的解决方案是,在尝试检查recv标志之前,我必须先RECVMORE。这不是您的答案。”

首先,它在答案中 WAS -第一个句子:
“ ...代码必须主动假定每条消息可能都由多部分组成,消息(在此为零保修,先验程度较小),并在之后后积极检查ZMQ_RECVMORE标志的存在然后再调用.recv()方法,直到.getsockopt( ZMQ_RECVMORE )方法说不过去。“


我这一代人深信不疑,如果基于错误的假设,我们犯了错误或做出了错误的决定,我们将永远不会惩罚任何其他人,因为我们犯了错误的决定。 令人惊讶的是,不在这里工作。为什么有人会惩罚一个伸出援助之手来帮助您解决问题并提出个人需要的人?没有人会愿意这种文化来寻求赞助人的帮助并惩罚任何这样做的人,这种情况会进一步发展。这难道不是一种自大自大的行为吗?无论是前者还是后者,这都不公平,要推广的样式越少,作为社区首选行为的回报就越少。 “参数”本身是空的,无效的-没有调用.recv()方法,ZeroMQ-API抽象视野内部什么也没有得到,更不用说.getsockopt()承诺学习的指示了-方法在获取RECVMORE标记中的使用(确定一些.recv()已得到实质内容后,-Message-这是基本的,不需要“包含”它在有关ZeroMQ / JeroMQ消息传递的任何文字中,因为它是不言自明的?有人会声称,不解释说,到目前为止是否没有发送电子邮件,要求电子邮件附加是没有道理的,这是不公平的吗?因此,“答案”的含义恰恰相反-它对此有所警告,即对于每个.recv()版消息,专业设计人员应始终假设使用 { 0+ }-RECVMORE-标记的多部分消息组件,它们遵循第一个.recv()版本,需要从API中挖掘出来。

最后一句话:

“也可以使用ZMsg。”

此声明仍然是一个无法确定的问题,因为O / P包含有关版本的零信息。自从首次发布版本通过v2.0-v2.1 -..- v2.11,通过v3.0-v3.1-v3.2,通过v4.0-v4.1-进行重构和扩展以来,Native ZeroMQ API一直在发展。 v4.2-v4.3并仍在计数,并且肯定不会在较早的实现中出现“声明的” Zmsg-抽象,因此版本号是最主要的(也是StackOverflow的一部分)带有重现问题的MCVE / MWE代码和所有相关细节的好方法的实践,版本号是其中的一部分,不是吗?)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...