Spring Boot配置好websocket后访问端点连接失败

79 阅读1分钟
首先展示配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    private static long HEART_BEAT = 20000;
    @Autowired
    private HandshakeInterceptor handshakeInterceptor;
    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        stompEndpointRegistry.addEndpoint("/ws").addInterceptors(handshakeInterceptor).setAllowedOrigins("*").withSockJS();
    }
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
  
        ThreadPoolTaskScheduler te = new ThreadPoolTaskScheduler();
        te.setPoolSize(10);
        te.setThreadNamePrefix("wss-heartbeat-thread-");
        te.initialize();
        registry.enableSimpleBroker("/deviceInfo","/patientInfo","/dashboard","/deviceExceptionStatus","/topic/messages").
                setHeartbeatValue(new long[]{HEART_BEAT,HEART_BEAT}).setTaskScheduler(te);;
        registry.setApplicationDestinationPrefixes("/ws");
    }}
HandshakeInterceptor中只进行了连接前后的日志输出。
然后通过调试工具访问ws://localhost:8801/ws显示连接失败:

98d0a8487c004a8a8b52a0652e330e79.jpg

访问ws://localhost:8801/ws/websocket显示连接成功:

1f6a09611dab4de3915459cf2a2b7cb3.png

为什么配置里设置的端点是/ws但是却访问不了呢。查了一下应该是使用了.withSockJS()的原因,使用时会为不支持WebSocket的浏览器添加回退选项(但是我用edge访问/ws也失败了,不太懂),其中一个回退选项就是 /websocket,由于不太懂前端Socket.IO也不知道加不加.withSockJS()有什么影响,所以这里直接删掉,然后访问ws://localhost:8801/ws成功。


接着又问了一下ai,删掉.withSockJS()会让前端只能使用原生的websocket,现在把.withSockJS()加回来,然后在浏览器控制台粘贴以下代码并发送:

 // 引入SockJS和Stomp.js库
    var script1 = document.createElement('script');
    script1.src = 'https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js';
    document.head.appendChild(script1);

    var script2 = document.createElement('script');
    script2.src = 'https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js';
    document.head.appendChild(script2);

    // 等待脚本加载完成后执行WebSocket连接代码
    script2.onload = function() {
        // 创建WebSocket连接
        var socket = new SockJS('http://localhost:8801/ws');
        var stompClient = Stomp.over(socket);

        // 连接成功后的回调函数
        stompClient.connect({}, function (frame) {
            console.log('Connected: ' + frame);

            // 发送消息到 /ws/session
            stompClient.send("/ws/session", {}, JSON.stringify({'content': 'Test message for session'}));

            // 发送消息到 /hello
            stompClient.send("/ws/hello", {}, JSON.stringify({'content': 'World'}));
        });
    };

/ws/session和/ws/hello是我controller中的方法。上述内容发送后显示连接成功。