SpringCloud处理Websocket消息过长自动断开连接

SpringCloud处理Websocket消息过长自动断开连接

问题描述

近期实现了客户端订阅Websocket后,服务端定期向客户端推送相关设备消息的功能,在本地测试没有问题,上线后却发现订阅设备数量超过一定数量后Websocket就会自动断开连接

报错日志

tex 复制代码
java.lang.IllegalStateException: Message will not be sent because the WebSocket session has been closed
	at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:449) ~[tomcat-embed-websocket-9.0.79.jar:9.0.79]
	at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:307) ~[tomcat-embed-websocket-9.0.79.jar:9.0.79]
	at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:249) ~[tomcat-embed-websocket-9.0.79.jar:9.0.79]
	at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:191) ~[tomcat-embed-websocket-9.0.79.jar:9.0.79]
	at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendObject(WsRemoteEndpointImplBase.java:614) ~[tomcat-embed-websocket-9.0.79.jar:9.0.79]
	at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendObject(WsRemoteEndpointBasic.java:72) ~[tomcat-embed-websocket-9.0.79.jar:9.0.79]
	at tbea.websocket.SubscribeDeviceParamWebSocketServer.lambda$scheduleMessagePush$2(SubscribeDeviceParamWebSocketServer.java:305) ~[classes/:na]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_301]
	at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) ~[na:1.8.0_301]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) ~[na:1.8.0_301]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_301]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[na:1.8.0_301]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_301]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_301]
	at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_301]

问题排查

经过排查发现当Websocket服务段推送消息数据大小在50kb左右时功能正常,此时再增加订阅一个设备时,线上Websocket就会自动断开连接,这时候很容易想到可能是Websocket推送消息可能又大小限制,当消息超过64kb的时候可能会自动断连。

然而我在本地测试发现消息数据大小远远超过64kb,仍然没有断连,客户端依旧可以收到消息。

这时发现我本地测试时,直接调用的是提供该功能服务的端口,而线上调用的是网关(gateway),再次测试发现,通过网关订阅Websocket时消息数据大小超过64kb时确实会自动断连。

解决方法

知道问题原因之后,直接通过搜索引擎发现Spring Cloud Gateway可以通过spring.cloud.gateway.httpclient.websocket.max-frame-payload-length配置来修改消息体的大小限制

修改gateway配置文件如下:

yaml 复制代码
spring:
  cloud:
    gateway:
      httpclient:
        websocket:
          # websocket数据包最大字节数
          max-frame-payload-length: 6553600

修改配置文件后,重新部署gateway发现功能正常。

相关推荐
闲猫8 小时前
Spring AI Agentic 模式(第1部分):Agent Skills——模块化、可复用的能力
java·人工智能·spring
JerrySir8 小时前
Node.js WebSocket 优雅关闭:一次滚动发布如何避免 1 万次重连风暴
websocket
952369 小时前
RabbitMQ-基础操作
java·spring boot·分布式·后端·spring·rabbitmq
卓怡学长10 小时前
w266基于spring boot + vue 圣地延安美食乐享系统
java·数据库·vue.js·spring boot·spring·intellij-idea
CryptoPP10 小时前
BSE股票K线数据接入实战:从接口调用到前端图表展示
大数据·前端·网络·人工智能·websocket·网络协议
worilb12 小时前
Spring Cloud 学习与实践(13):使用 Seata 解决分布式事务问题
分布式·学习·spring cloud
宠友信息12 小时前
多端即时通讯源码技术实践,Redis路由、MySQL持久化与Socket接入
spring boot·websocket·mysql·uni-app
Devin~Y13 小时前
电商场景下的Java面试实战:从Spring Boot微服务到Kafka、Redis与AI RAG
java·spring boot·redis·elasticsearch·spring cloud·微服务·kafka
SizeTheMoment14 小时前
Spring Cloud 微服务认证体系深度解析:从架构设计到安全实践
安全·spring cloud·微服务
wang090714 小时前
自己动手写一个spring之MVC_3
java·spring·mvc