将 ack 设置为客户端会导致重复的消息传递 stomp

setting ack to client results in duplicate message delivery stomp

我有一个 stomp 应用程序,我在从 front-end 订阅期间将 ack 模式设置为 client。在订阅期间,session 期间的同一客户端将连接到消息代理 ActiveMQ Artemis 中的相同 queue,因为 session id 用于 queue.But 传递了不同的 id每次用户重新加载页面时 header。

订阅码如下所示

            consumer.subscribe(
                '/queue.'+ rscSessionId,
                function (response) {
                    console.log("resposne");
                },
                {
                    "subscription-type": "ANYCAST",
                    ack: "client",
                    id: generateId(),
                }
            );

一旦我从客户端发送消息,它就会通过以下 headers 发送到前端。

MESSAGE
subscription:1234
message-id:1543449
destination:/queue.sessionid
expires:1653914606725
redelivered:false
priority:4
persistent:true
timestamp:1653912806717
destination-type:ANYCAST
__AMQ_CID:30e64793-dd9b-11ec-8843-c238460c3152
_type:ResponseData
content-length:300

之后每次重新加载时。

MESSAGE
subscription:1235
message-id:1543449
destination:/queue.sessionid
expires:1653914606725
redelivered:true
priority:4
persistent:true
timestamp:1653912806717
destination-type:ANYCAST
__AMQ_CID:30e64793-dd9b-11ec-8843-c238460c3152
_type:ResponseData
content-length:300

您可以看到 redelivered 在第一次发送后设置为 true,之后每个响应都有 redeliveredfalse。由于 header.

中传递的 idsubscription 值不断变化

怎样才能保证只送一次?

我猜 Artemis 配置了 publisher/subscriber 消息传递样式。在这种情况下,每个新 consumer/receiver/client 都会从一个主题中收到消息,也就是您 write/read。

更改为 point-to-point 消息样式将解决问题(只能读取一次)也就是队列。

这通常由设置决定,但我记得 ActiveMQ 允许生产者即时创建这些。

如果您确实需要主题,则必须在客户端处理 ID。

收到消息后,您真的确认了吗?如果您不确认该消息,那么一旦客户端关闭连接并再次订阅,它将再次收到相同的消息。您看到的 subscription header 的不同值表明这是正在发生的事情。

需要说明的是,如果您使用 client 确认模式,那么一旦您收到 MESSAGE 帧,您需要发送相应的 ACK 帧以确认信息。你的客户应该有办法做到这一点,因为它是 STOMP 规范的标准部分。