【发布时间】:2019-01-17 02:17:18
【问题描述】:
我正在使用 Artemis 2.6.2 仅与 STOMP 和以下星座:
经纪人:
- broker.xml 中没有配置队列,一切都是自动创建的。
服务器:
- 订阅目的地
TaskResponse,不带选择器/过滤器 - 发送到目标
TaskRequest,标头clientId = ID(服务器请求的客户端ID)
客户端 123:
- 订阅目的地
TaskRequest,选择器clientId = 123 - 发送到目的地
TaskResponse,标头clientId = 123
当我在Artemis Console 观看时,会发生以下情况:
没有连接服务器和客户端:不存在地址或队列
服务器连接:
Artemis创建一个多播地址TaskResponse和一个带有空过滤器的地址的多播队列客户端 123 连接:
Artemis创建一个多播地址TaskRequest和该地址的多播队列,过滤器 clientId = 123消息交换:消息按预期从服务器传输到客户端并返回到服务器。
客户端 123 断开连接:
Artemis删除多播地址TaskRequest和过滤器 clientId = 123 的对应多播队列服务器向客户端 123 的 TaskRequest 发送消息:根据服务器上的
STOMP客户端消息发送成功。在代理上,消息消失了。反之亦然:客户端 123 已连接而服务器未连接:根据客户端 123 上的
STOMP客户端,消息发送成功。在代理上,消息消失了。
我的猜测是消息被丢弃是因为没有到订阅者的路由。如果我在 broker.xml 的地址设置部分启用“send-to-dla-on-no-route”选项,则消息直接进入死信队列。
您知道在订阅者重新连接之前保留消息的方法吗?
附录 1:STOMP 消息
我将Stomp.Net Library 与SelectorsCore Example 一起使用,但仅简化为选择器s1。工作流程与我上面写的有点不同。
不幸的是,我没有找到将 STOMP 消息记录到 Artemis 文件中的示例。因此我用WireShark记录了数据包,导出为文本并上传到Gist StompMessages.txt。您可以在那里看到不同的 STOMP 消息,例如搜索 CONNECT、SEND 等。
解决方案
解决方案是在broker.xml 的acceptor 元素中使用选项anycastPrefix=/queue/ 来强制队列输入ANYCAST:
<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;anycastPrefix=/queue/</acceptor>
【问题讨论】: