文章背景
最近公司有个小项目需要时候即时通讯,类似那种抢答小游戏,我想这不得用上websocket组件嘛,之前这种项目我一般都会依赖于第三方成熟的服务,比如直接用腾讯,阿里或者其他的IM服务,技术成熟又稳定,基本能实现你websocket的所有需求,但是我想着这玩意这么简单,我自己弄个websocket来玩玩吧,结果遇到了一下问题,分享解决过程。
前端
最开始使用原生websocket方案 var Socket =new WebSocket(url, protocol );
你会发现未了维持长连接的高可用性,前端你需要对WebSocket做很多措施,主要就是断线重连机制的以下问题
- 断线检测,
- 超时控制,
- 重连尝试时间
- 最大重连次数
这些你都需要来自己进行处理,个人推荐你可以使用ReconnectingWebSocket, https://www.npmjs.com/package/reconnecting-websocket
这个第三方库,他能控制以上几个配置,保证客户端的可用性。
nginx配置
什么情况下会出现websocket断线,其实websocket 当断线时会提供CloseStatus给用户做反馈,我们可以通过一下错误码来缩小问题范围
最开始我发现websocket在1分钟内没触发消息就会自动断开长连接,错误码是1006,
大多情况都是因为websocket 连接在nginx 配置的 proxy_read_timeout 内没有收到数据,nginx主动发起的连接断开(不是客户端主动断开,也不是服务端主动断开的)。为什么是60秒,其实nginx的默认是proxy_read_timeout 就是60秒,导致1分钟内,你没触发信息,nginx给杀掉了,处理这个方案就其实也很简单
- 增大nginx的proxy_read_timeout 时间设置;
- 减小服务端和客户端之间的心跳间隔;
这样处理后,触发断线重连的概率变小很多了
结语
总结一下整体经验
前端
- 使用 ReconnectingWebSocket 库保证长连接的可用性
- 一定要做心跳机制
nginx
- 调整 proxy_read_timeout 值,稳定长连接
服务端
- 做好重连后长连接 session 的处理,因为重连后他就是一个新的连接,系统将会为它重新分配session,你需要做好替换的处理逻辑处理
做完以上工作,肯定还有些披露希望各位大佬评论交流。正经项目还是不要像我这样自己维护 WebSocket 直接用第三方的 IM 服务就行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。