寒夜憨憨 2024-04-27 11:30 采纳率: 71.4%
浏览 50

websocket无数据交互断连问题

在springboot和vue中使用rabbitmq做消息代理的websocket通信(服务端和客户端都默认开起了10000ms的心跳机制),当在一段时间内服务端和客户端无数据交互的情况下,当前连接会被断开,后端服务器日志”CloseStatus[code=1002, reason=null]“,前端控制台显示日志“sockjs.min.ce85c5ca.js:2 Uncaught Error: InvalidStateError: The connection has not been established yet”和“<<< ERROR
message:Connection to broker closed.
content-length:0”,具体前端日志情况如下图:

img

img

若前端设置心跳机制间隔时间为0(关闭心跳机制)(后端使用rabbitmq做消息代理设置心跳机制时间或者关闭不生效“setSystemHeartbeatReceiveInterval和setSystemHeartbeatSendInterval”)或者服务端和客户端有数据交互,那么就不会出现断连的情况请问各位本博主有没有解决方案?感谢!

下面附图后端配置:

img


下面附图前端配置:

img

  • 写回答

6条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-27 11:30
    关注

    引自免费微信小程序:皆我百晓生

    针对您描述的问题,WebSocket 在没有数据交互时自动断开连接可能是因为双方的心跳检测机制导致的。为了保持连接稳定,可以尝试调整双方的心跳检测参数,确保它们足够匹配且不会过早地断开空闲连接。

    首先,针对 Spring Boot 配置,您可以尝试将心跳发送和接收的时间间隔调大一些,例如设置为60秒。同时,确认 RabbitMQ 消息代理中的心跳设置是否有效。尽管您已经设置了 setSystemHeartbeatReceiveIntervalsetSystemHeartbeatSendInterval,但仍然建议检查 RabbitMQ 服务器的配置文件(通常是 rabbitmq.configrabbitmq-env.conf)以确认这些值是否被正确应用。

    Spring Boot 配置示例:

    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry config) {
            config.enableSimpleBroker("/topic", "/queue")
                    .setHeartbeatValue(new Long[]{60000, 60000});
            
            // 如果使用RabbitMQ作为消息代理
            config.enableStompBrokerRelay("/topic", "/queue")
                    .setSystemHeartbeatReceiveInterval(60000)
                    .setSystemHeartbeatSendInterval(60000)
                    .setRelayHost(rabbitmqHost)
                    .setRelayPort(stompPort)
                    ...
        }
    }
    

    对于前端 Vue 应用,由于 WebSocket 连接是通过 SockJS 实现的,而 SockJS 自动管理心跳,并且基于底层协议的不同(如 XHR 轮询、WebSockets 等)可能会有不同的行为。不过,一般来说,如果你使用的是 sockjs-client,它会自动处理心跳,不需要额外配置。但是,如果您想手动调整心跳频率,可以使用 sockopt 方法设置:

    let socket = new SockJS('http://localhost:8083/chat');
    socket.sockopt({
        heartbeatDelay: 60000 // 设置心跳延迟为60秒
    });
    
    const stompClient = Stomp.over(socket);
    stompClient.connect({}, onConnect, onError);
    

    这样,您的前端和后端都设置了一个较长的心跳间隔,应该能避免在没有数据交互的情况下断开连接。请注意,这个间隔设置应根据实际应用场景进行调整,以防止不必要的资源消耗。

    最后,请确保您的网络环境和防火墙设置允许长时间的WebSocket连接。有时候,防火墙可能会因为长时间无数据传输而中断连接。如果问题依然存在,可能需要进一步排查网络环境或服务器配置。

    评论 编辑记录

报告相同问题?

问题事件

  • 修改了问题 4月27日
  • 创建了问题 4月27日

悬赏问题

  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥20 spring boot集成mqtt的使用问题
  • ¥15 使用百度地图api 位置函数报错?
  • ¥15 metamask如何添加TRON自定义网络
  • ¥66 关于川崎机器人调速问题
  • ¥15 winFrom界面无法打开
  • ¥30 crossover21 ARM64版本安装软件问题
  • ¥15 mymetaobjecthandler没有进入
  • ¥15 mmo能不能做客户端怪物
  • ¥15 osm下载到arcgis出错