WebSocket应用部署到生产环境,我们除了会碰到因为经过代理服务器无法连接的问题(注:该问题可以通过搭建WSS来解决,具体配置请看 WebSocket实战之四WSS配置 ),另外一个问题就是外网环境不稳定经常会断开或者服务器重启或者网络中间服务器当发现一个长连接长时间没有传输数据会断开,今天我们来了解一下基于WebSocket如何做心跳重连。
关于心跳包的格式,WebSocket协议RFC6455中有定义控制帧的格式.
Ping帧包含一个操作码 0x9,Pong帧包含一个操作码 0xA。
客户端发送Ping帧,服务端收到Ping帧后回一个响应Pong帧。
但是JavaScript 并没有API支持Ping、Pong帧,而后端JavaEE是有PingPong的支持,这是很奇怪的事情,那我们就通过自定义消息来定义心跳包。
对 WebSocket实战之五JSR356 这篇文章WebSocketServer类进行修改,配置一个定时器,每隔10秒定时发送当前时间,并且在onMessage事件中加上接收心跳包以及发送心跳包的代码,服务端对心跳处理相对简单。
注:需要使用一个容器将请求的Session保存起来并且使用static,否则在发送信息时拿不到原来的那个session对象。
说明:
1、所有异常都加上重连代码,包含创建WebSocket连接、onClose事件、onError事件。
2、在onOpen和onMessage启动心跳包发送。
3、心跳包发送方法设置两个延迟器一个用于发送心跳包,另外一个用于当服务端超时(如果服务端未超时会发送响应心跳包然后重新调用heartCheck将两个延迟器清空)关闭WebSocket连接。
4、重连代码时序:当服务端Down掉或网络断开超过一定时间serverTimeoutObj这个延迟器会执行,然后调用ws.close()关闭连接并且触发onClose事件,在onClose事件中会调用reconnect方法,而reconnect又会调用createWebSocket方法,createWebSocket去创建WebSocket连接,当创建异常时又会再调用reconnect,一直到能连接得上。