Spring websockets:消息未发布
Posted
技术标签:
【中文标题】Spring websockets:消息未发布【英文标题】:Spring websockets: message not published 【发布时间】:2016-05-20 11:36:20 【问题描述】:我将 Spring WebSockets 与 STOMP 和 SockJS 一起用于前端。它工作正常,但我还有另一个困难。
这是后端代码:
@MessageMapping("/showAccountlist")
@SendTo("/topic/accounts")
public Account createPublishAccount(String name) throws Exception
return new Account(name);
这是前端代码,可以正常工作,所有消息都会发布到所有客户端。
stompClient.send("/app/showAccountlist", , name);
但是当我调用我的后端方法时从我的java后端,方法名称
createPublishAccount("Carlos");
似乎消息没有被发布。有什么解决办法吗?或者这不是它的工作方式,它只有在通过 SockJS 触发时才有效?
这是我的网络配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
@Override
public void configureMessageBroker(MessageBrokerRegistry config)
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
@Override
public void registerStompEndpoints(StompEndpointRegistry registry)
registry.addEndpoint("/showAccountlist").withSockJS();
【问题讨论】:
具有 createPublishAccount 方法的类是否被 Spring 实例化? 似乎不可能通过调用@SendTo注解的方法来发送消息。使用SimpMessagingTemplate
可以吗?
当然。见docs.spring.io/spring/docs/current/spring-framework-reference/…
@Jakub Bibro 感谢 SimpMessagingTemplate 的作品。如果您可以以描述性方式和代码示例更新您的答案。我会接受的
【参考方案1】:
调用@SendTo 注解的方法似乎无法发送消息。
Spring推荐的消息发送方式是使用SimpMessagingTemplate
。例如在convertAndSendToUser
方法(http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/messaging/simp/SimpMessagingTemplate.html)中,可以将目标作为参数(在您的情况下为/topic/accounts
)。
请参阅 Spring 文档的摘录 (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-handle-send):
如果您想从应用程序的任何部分向连接的客户端发送消息怎么办?任何应用程序组件都可以向“brokerChannel”发送消息。最简单的方法是注入一个 SimpMessagingTemplate,并使用它来发送消息。通常它应该很容易按类型注入,例如:
@Controller
public class GreetingController
private SimpMessagingTemplate template;
@Autowired
public GreetingController(SimpMessagingTemplate template)
this.template = template;
@RequestMapping(path="/greetings", method=POST)
public void greet(String greeting)
String text = "[" + getTimestamp() + "]:" + greeting;
this.template.convertAndSend("/topic/greetings", text);
【讨论】:
谢谢,赏金也将在 20 小时内被接受。我在这里有一个问题。方法“convertAndSend”也接受参数“user”,向特定用户发送消息。但无法弄清楚如何使用它。这里的用户是什么?如果某个账户收到了钱,我需要更新客户端的余额信息。 这适用于 spring security 的 Principal 名称。有关详细信息,请参阅docs.spring.io/spring-security/site/docs/current/reference/html/…。所以spring根据队列名称和主体名称,将其转换为特定的队列名称,消息将传递给特定的用户。 我的应用不使用身份验证,在这种情况下我还能使用 Spring Security 吗?也许每次建立 websocket 连接时,我都需要在客户端默默地生成一个随机用户名? 是的,你可以在你的项目中添加spring security,因为你需要确保用户只接收自己的消息。请参阅 docs.spring.io/spring/docs/current/spring-framework-reference/… 和 docs.spring.io/spring/docs/current/spring-framework-reference/…。 “Spring 的 STOMP WebSocket 支持期望用户已经通过 HTTP 进行了身份验证”。但公平地说,有一个选项可以通过 websocket 会话以某种方式区分用户。很大程度上取决于您要解决的问题。 谢谢我通过简单的 /topic/balance/$pageContext.session.id 解决了这个问题,并将会话 ID 附加到所有帐户以上是关于Spring websockets:消息未发布的主要内容,如果未能解决你的问题,请参考以下文章
Spring(Grails)WebSocket 立即记录错误:SubProtocolWebSocketHandler - *** ms 后未收到消息