将 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
,之后每个响应都有 redelivered
到 false
。由于 header.
中传递的 id
,subscription
值不断变化
怎样才能保证只送一次?
我猜 Artemis 配置了 publisher/subscriber 消息传递样式。在这种情况下,每个新 consumer/receiver/client 都会从一个主题中收到消息,也就是您 write/read。
更改为 point-to-point 消息样式将解决问题(只能读取一次)也就是队列。
这通常由设置决定,但我记得 ActiveMQ 允许生产者即时创建这些。
如果您确实需要主题,则必须在客户端处理 ID。
收到消息后,您真的确认了吗?如果您不确认该消息,那么一旦客户端关闭连接并再次订阅,它将再次收到相同的消息。您看到的 subscription
header 的不同值表明这是正在发生的事情。
需要说明的是,如果您使用 client
确认模式,那么一旦您收到 MESSAGE
帧,您需要发送相应的 ACK
帧以确认信息。你的客户应该有办法做到这一点,因为它是 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
,之后每个响应都有 redelivered
到 false
。由于 header.
id
,subscription
值不断变化
怎样才能保证只送一次?
我猜 Artemis 配置了 publisher/subscriber 消息传递样式。在这种情况下,每个新 consumer/receiver/client 都会从一个主题中收到消息,也就是您 write/read。
更改为 point-to-point 消息样式将解决问题(只能读取一次)也就是队列。
这通常由设置决定,但我记得 ActiveMQ 允许生产者即时创建这些。
如果您确实需要主题,则必须在客户端处理 ID。
收到消息后,您真的确认了吗?如果您不确认该消息,那么一旦客户端关闭连接并再次订阅,它将再次收到相同的消息。您看到的 subscription
header 的不同值表明这是正在发生的事情。
需要说明的是,如果您使用 client
确认模式,那么一旦您收到 MESSAGE
帧,您需要发送相应的 ACK
帧以确认信息。你的客户应该有办法做到这一点,因为它是 STOMP 规范的标准部分。