Spring Websocket + SockJS中SimpleMessageBroker的/topic和/queue之间的区别

21
使用简单代理时,Spring Websocket + SockJS中的/topic、/queue等之间有什么区别?比如在这里Sending message to specific user on Spring Websocket中,有这样一段话:当您的客户端订阅以/user/开头的频道时,例如:/user/queue/reply,您的服务器实例将订阅一个名为queue/reply-user[session id]的队列。我想以一种清晰的方式理解这些转换背后的逻辑。
3个回答

18

你应该查看参考文档中的这部分内容

简而言之,"/topic""/queue"是配置到相同目标的前缀。

在文档中,"/app"是配置的“应用程序目标前缀”- 意思是通过"clientInboundChannel"流入且匹配这些前缀的所有消息都将映射到您的应用程序,例如使用@MessageMapping注解。

在这里,"/topic""/queue"也是配置为STOMP目标的前缀- 意味着通过"clientInboundChannel"流入且匹配这些前缀的所有消息都将转发到STOMP代理。对于你的情况,那是简单代理实现。

因此,从Spring Websocket的角度来看,"/queue""/topic"被视为相同并且是“典型”的STOMP目标- 所有匹配它们的消息都将被转发到消息代理。现在,如果你正在使用完整的消息代理实现,这些目标可能不具有相同的含义,消息代理的行为可能不同。以下是使用Apache ApolloRabbitMQ的一些示例。

请注意,如果您愿意,可以更改这些前缀。但我建议你保持这些默认值,除非你确实知道你在做什么。


2
请问,/topic和/queue之间实际上有什么区别?现在不清楚,我应该使用其中的一个还是可以自己创造。 - onkami
1
我已经更新了我的回答。对于简单的消息代理,这根本没有任何区别。但是我已经明确指出,在使用真正的消息代理(如果您需要部署多个应用程序实例)时,这些目标可能具有不同的含义。 - Brian Clozel

8
我认为这个主题的最佳答案来自Spring Docs的如下部分:
目标的意义在STOMP规范中故意保持不透明。它可以是任何字符串,完全由STOMP服务器定义支持的目标的语义和语法。然而,通常情况下,目标是类似于路径的字符串,其中“/topic/..”表示发布-订阅(一对多),“/queue/”表示点对点(一对一)消息交换。

6

以上回答中没有提到更重要的区别,即主题(Topic)是自动删除的,而队列(Queue)是持久化的。这意味着当 WebSocket 连接关闭时,主题及其数据将被删除。在队列中,服务器仍然可以发送消息,并且当客户端通过 WebSocket 连接时,它会接收到服务器先前发送的消息。

另外,在内存代理中没有区别。这种情况发生在使用专用代理时。


请问您能否添加相关文档的引用? - Sergey
1
Spring框架5.0.0.M4的文档中提到:“‘/topic’和‘/queue’前缀取决于使用的代理”,以及“查看代理的STOMP页面以了解其支持的目标语义”。我之前提到的答案是针对RabbitMQ的。我不知道其他代理是否也是这样。 - denizg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接