【问题标题】:How to detect Spring websocket stomp subscription messages (frames)?如何检测 Spring websocket stomp 订阅消息(帧)?
【发布时间】:2019-02-14 23:35:12
【问题描述】:

我使用的是 Spring 5:如何检测来自 Stomp 客户端的 SUBSCRIBE 消息?

根据我的理解,@SubscribeMapping 应该让我的控制器方法在客户端订阅主题时被调用,但这并没有发生。

这是我的服务器控制器:

@Controller
public class MessageController {

    // ...

    @MessageMapping("/chat/{mId}")
    @SendTo("/topic/messages")
    public OutputMessage send(Message message, @DestinationVariable("mId") String mid, MessageHeaders headers, MessageHeaderAccessor accessor) throws Exception {
        // ...
    }

    @SuppressWarnings("unused")
    @SubscribeMapping({ "/", "/chat", "/topic/messages", "/messages", "/*" })
    public void listen(Message message, MessageHeaders headers, MessageHeaderAccessor accessor) throws Exception {
        int i = 0;
        System.out.println("subscribed");
    }

}

服务器配置:

@Configuration
@ComponentScan(basePackages= { "websockets" })
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
         registry.addEndpoint("/chat");
         registry.addEndpoint("/chat").withSockJS();
    }

    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
        WebSocketMessageBrokerConfigurer.super.configureWebSocketTransport(registry);
    }
}

还有 javascript 客户端:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Chat WebSocket</title>
        <script src="sockjs.js"></script>
        <script src="stomp.js"></script>

        <script type="text/javascript">

            // ...

            function connect() {
                var sock = new SockJS('/<webapp-context>/chat');

                stompClient = Stomp.over(sock);  
                stompClient.connect({}, function(frame) {
                    setConnected(true);
                    console.log('Connected: ' + frame);
                    stompClient.subscribe('/topic/messages', function(messageOutput) {
                        showMessageOutput(JSON.parse(messageOutput.body));
                    });
                    stompClient.subscribe('/topic/messages/13', function(messageOutput) {
                        showMessageOutput(JSON.parse(messageOutput.body));
                    });
                });
            }

            // ...

        </script>
    </head>
    <body onload="/*disconnect()*/">

        <!-- ... -->

    </body>
</html>

代码改编自Intro to WebSockets with Spring。

如this answer 和in the docs 所示,我可以只使用拦截器,但@SubscribeMapping 是如何工作的呢?

【问题讨论】:

    标签: java spring spring-websocket spring-messaging


    【解决方案1】:

    您还需要将“主题”注册为应用程序目标主题config.setApplicationDestinationPrefixes({"/app", "/topic"});。

    否则 Spring 不会将订阅消息转发到应用程序,而只会将其转发到消息代理通道。

    【讨论】:

    • 就是这样!谢谢。
    • 对读者的补充说明:Spring 在转发到应用程序之前会去除 /topic 前缀。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 2018-11-05
    • 2020-01-07
    • 2014-09-07
    • 2020-12-17
    • 2023-03-17
    相关资源
    最近更新 更多