我正在使用Spring stomp websocket框架向客户端发送订阅消息。我们使用ActiveMQ作为消息代理 并正在使用stomp javascript客户端。 Spring 4.1.5和在这个架构中,消息是使用
发送的simplemessagingTemplate.convertAndSendToUser(user, "/queue/msg", serverMsg, map);
为了确保只有正确的用户收到他们的消息,我也在使用实现ChannelInterceptor的QueueSubscriptionInterceptor。 消息正确传递到目标。使用这样的JS客户端接收消息。
stompClient.subscribe('/user/guest/queue/msg', function(greeting){
x = JSON.parse(greeting.body);
...
}
到目前为止一切顺利。但是,当存在多个用户会话时,只有一个会话接收该消息。对于(例如),如果有两个“来宾”用户 登录后,我希望所有两个“访客”用户都收到该消息。这似乎没有发生。看着日志, 我看到该消息似乎已发送..
2015-04-11 14:39:40 DEBUG StompBrokerRelayMessageHandler:738 - Forwarding SEND /queue/msg-user1 session=_system_ application/json;charset=UTF-8 payload={"my message to you...)
2015-04-11 14:39:40 DEBUG StompBrokerRelayMessageHandler:738 - Forwarding SEND /queue/msg-user0 session=_system_ application/json;charset=UTF-8 payload={"my message to you...)
我看到只有一个客户端收到邮件而不是另一个客户端。阅读Spring文档,我知道这是默认行为。 有人能告诉我我做错了什么。
感谢。
答案 0 :(得分:2)
您应该使用主题的语义而不是队列。
队列允许消息被消费一次,但是一个主题将允许每个订阅者使用一次消息。所以像/ topic / user / guest / msg这样的东西可能会这样做。
答案 1 :(得分:0)
在连接框架中设置ack头。这将使服务器继续向您发送相同的消息,直到您发回一个确认帧为止。我在下面通过接收到消息立即调用greeting.ack()来执行此操作。将其设置为“单个客户端”将意味着服务器必须从特定客户端的所有会话中接收确认,否则它将继续在每个CONNECT上重新发送相同的消息。 希望这可以帮助!! 使用下面的代码作为参考。
function connect() {
var socket = new SockJS('/powerme-notification-websocket');
stompClient = Stomp.over(socket);
stompClient.connect(
{client_id:'testClient'}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/user/topic/releaseLock', function (greeting) {
stompClient.subscribe('/queue/releaseLock-testClient', function (greeting) {
console.log(greeting);
showGreeting(greeting.body);
greeting.ack();
},{durable:true,
'auto-delete':false,
ack:'client-individual',
id:'testClient'});
});
}
参考: https://stomp.github.io/stomp-specification-1.2.html#ACK