WebSocket 频繁爆出异常

2023-10-23 09:55:27 +08:00
 looveh

做了个 WebSocket 连接,客户端通过定时发送心跳。但是时间一长发现还是会自动断开,心跳时间是 30s 一次,ng 也做了如下配置:

proxy-read-timeout:'3600'
proxy-send-timeout:'3600'

有没有大佬出现过这种情况? 错误如下:

 java.io.EOFException: null

 	at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1345)

 	at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1255)

 	at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:75)

 	at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:183)

 	at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:162)

 	at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:156)

 	at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60)

 	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59)

 	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)

 	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)

 	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)

 	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)

 	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)

 	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

 	at java.base/java.lang.Thread.run(Thread.java:829)
1941 次点击
所在节点   WebSocket
23 条回复
coderxy
2023-10-23 10:02:27 +08:00
断开很正常吧? 中间任何一个环节网络波动啥的都会导致断开, 做好重连不就行了?
opengps
2023-10-23 10:03:19 +08:00
公网环境下,通信要做的就是断线自动重连,而不是一个连接用到老
stinkytofu
2023-10-23 10:07:59 +08:00
也可以找一个成熟的库, 库内部维护连接, 就不用操那么心了
skcy
2023-10-23 11:02:13 +08:00
如果是浏览器 tab 在非激活状态,或者电脑休眠的时候,浏览器内定时器 会触发 任务 延时机制,可尝试 webworker (休眠依然无解)
nothingistrue
2023-10-23 11:14:22 +08:00
EOFException 是异常到达流尾部,这不一定是连接被断开了,你可能更需要关注 IO 流的生命周期,或者缓冲区的配置。

至于心跳,它更应该当作被断开的感知器,不应该作为连接维持的保证器。
gkinxin
2023-10-23 11:51:55 +08:00
@stinkytofu 有什么库推荐一下呢
stinkytofu
2023-10-23 11:55:50 +08:00
@gkinxin #6 EMQX
Parva
2023-10-23 11:58:25 +08:00
裸 websocket 手撸心跳?找些库、协议套一套吧
coyove
2023-10-23 12:07:35 +08:00
如果是浏览器的话,tab 切换,进入后台,safari 节能模式,都可能导致 websocket 不可用。这样的策略是无法预知的,只能做好重连
mmdsun
2023-10-23 12:41:18 +08:00
这是原生 websocket 吗?
我用 spring +STOM 很稳,spring 也推荐了客户端
https://docs.spring.io/spring-framework/reference/web/websocket/stomp.html
0xsui
2023-10-23 12:43:03 +08:00
建议你用 SocketIO ,比自己写的更完善,更稳定
looveh
2023-10-23 19:43:30 +08:00
@coderxy 前后端都有做数据流动,防止断线。但是有时候还是会有这种错误,而我们现在有个需求走这里,并且还需要送达率 100%😭
looveh
2023-10-23 19:43:58 +08:00
@opengps 有重连的哦,但是断开那瞬间如果有消息通过就丢了,我们的业务是消息需要 100%到达
looveh
2023-10-23 19:44:33 +08:00
@mmdsun 后面可能会改,现在就是要满足现有需求
looveh
2023-10-23 19:45:26 +08:00
@mmdsun 不过这个我看了一下,看不太明白😂太菜了
looveh
2023-10-23 19:46:04 +08:00
@coyove 重连是有做的
coderxy
2023-10-23 20:02:33 +08:00
@looveh 很正常,应该中间有很多环节都有可能把你的连接断掉, 要保证送达,该做的是离线消息。
looveh
2023-10-24 10:02:52 +08:00
@coderxy 离线消息怎么做😳
coderxy
2023-10-24 10:38:01 +08:00
@looveh 消息发送时入库,接收方断线重连时获取离线消息
looveh
2023-10-24 11:08:26 +08:00
@coderxy 我们这个消息实时性很高的😂必须实时推到

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/984391

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX