websocket Stomp未接收连接框架(Angular +Spring)

sg24os4d  于 2023-06-23  发布在  Angular
关注(0)|答案(1)|浏览(134)

我目前正在我的Sping Boot 2 + Angular 14应用程序上使用SockJS和Stomp实现后端到前端的消息机制
我得到一个随机的行为,有时一切工作,但有时WebSocket不接收任何消息。
当它不起作用时,WS消息如下所示

但一旦成功

主要的区别是,当它工作时,它会收到一个CONNECTED帧并触发订阅。我不明白为什么有时候它收不到CONNECTED帧。
我的后端配置

@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry
            .addEndpoint("/socket/no")
            .setAllowedOriginPatterns("*").withSockJS();
    }
}

前端客户端(app.component.ts > ngOnInit)

const socketUrl = `${window.origin}/socket/no`;
    const stompClient = new Client({
      brokerURL: socketUrl,
      connectHeaders: {},
      debug: function (str) {
        console.debug(str);
      },
      reconnectDelay: 5000,
      webSocketFactory: function () {
        return new SockJS(socketUrl);
      },
      onConnect: function () {
        stompClient.subscribe("/topic/no", function (msg) {
          console.log("message received");
        });
      },
    });

    stompClient.activate();

proxy.conf.json

"/socket/**": {
        "target": "http://localhost:8080",
        "secure": false,
        "ws": true
    },

我觉得当我在一个小页面上打开这个有Angular 的应用程序时,它更有可能工作。例如,我的主页有很多组件,需要一些时间来加载。但是,当我打开一个简单的网格视图的URL的应用程序,它有更多的机会工作,但不是所有的时间。
由于这种感觉,我认为这是一个前端问题。也许是WebSocket所需的angular组件,而不是loader或类似的东西。
在后端,在发送连接帧之后,我看到了这个日志

ms.w.s.h.LoggingWebSocketHandlerDecorator New WebSocketServerSockJsSession[id=naeygmcp]
qrjkbowd

qrjkbowd1#

您的WebSocket线程池可能已耗尽。默认情况下,线程池配置为:

core pool size = CORE * 2
max pool size  = CORE * 2
queue capacity = Integer.MAX_VALUE

成功连接STOMP客户端将经历以下阶段:
1.建立WebSocket连接(HTTP状态:101)
1.发送STOMP命令CONNECT
1.接收STOMP命令CONNECTED
1.发送STOMP命令SUBSCRIBE
1.发送STOMP命令SEND
第一个只是一个HTTP请求,所以它不会使用线程池。相反,STOMP协议下的剩余阶段将全部使用该池。也许你的应用中有一些长时间运行的请求占用了池,导致客户端在第二阶段卡住。
一种可能解决方案是调整池:

@Configuration
@EnableWebSocketMessageBroker
public class DefaultWebSocketMessageBrokerConfigurer implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration
                .taskExecutor()
                .corePoolSize(8)
                .maxPoolSize(512)
                .queueCapacity(32)
                .keepAliveSeconds(30);
    }
}

相关问题