大致思路:
- 连接上之后,每秒发送一个心跳,服务器同样返回一个心跳,用来表示服务器没挂。
- 断线重连(我们测试的环境是断开网络连接),断开网络后,心跳包无法发送出去,所以如果当前时间距离上次成功心跳的时间超过20秒,说明连接已经出现问题了,此时需要关闭连接。
- 第一次关闭连接时websocket会尝试重连,设置了一个时间期限,10秒。10秒内如果能连上(恢复网络连接)就可以继续收发消息,连不上就关闭了,并且不会重连。
- 30秒内收不到服务器消息(心跳每秒发送),我就认为服务器已经挂了,就会调用close事件,然后进入第3步。
cocos代码如下:
//心跳定时器
private _heartBeatTimer:number;
//心跳间隔时间
private HBIntervalTime:number = 1000;
private HEARTBEAT:string = "HeartBeat";
//延迟等待定时器
private _delayWaitTime:number;
/**
* 创建心跳定时器
*/
private resetHeartBeatTimer() {
clearTimeout(this._heartBeatTimer)
clearTimeout(this._delayWaitTime)
let self = this;
this._heartBeatTimer = setTimeout(function() {
if (self._ws)
{
console.log("send:"+self.HEARTBEAT);
self._ws.send(self.HEARTBEAT);
//发送超过20秒未响应就自动关闭socket
self._delayWaitTime = setTimeout(function(){
self.closeSocket(1)
},20000)
}
},this.HBIntervalTime)
}
private _ws:WebSocket;
/**
* socket
*/
public connectWebSocket(callfunc?:Function) {
if (!this._ws)
{
this._ws = new WebSocket("ws://echo.websocket.org");
let self = this;
this._ws.onopen = function(event) {
console.log("send text WS was opened");
//开始心跳检测
self.resetHeartBeatTimer();
if (callfunc)
{
callfunc();
}
}
//消息到达就回调
this._ws.onmessage = function(event) {
if (event.data==self.HEARTBEAT)
{
self.resetHeartBeatTimer();
}
console.log("response text msg: " + event.data);
}
this._ws.onerror = function (event) {
console.log("Send Text fired an error");
};
this._ws.onclose = function (event) {
console.log("WebSocket instance closed.");
};
}
}
/**
* socketSend
*/
public socketSend() {
if (this._ws.readyState == WebSocket.OPEN)
{
this._ws.send("hello")
}
else
{
console.log("WebSocket instance wasn't ready...");
}
}
//最后一次重连延迟器
private _lastReconnectTime:number;
/**
* closeSocket
* @param closeCount 断开次数
*/
private closeSocket(closeCount:number)
{
if (this._ws)
{
this._ws.close();
this._ws = null;
if (closeCount==1)
{
//断线重连
console.log("*******************reconncet**********************");
this.connectWebSocket();
let self = this;
//10秒时间,如果没有连接成功就关闭连接,并且再也不重连
this._lastReconnectTime = setTimeout(function(){
if (self._ws&&self._ws.readyState != WebSocket.OPEN)
{
self._ws.close();
this._ws = null;
}
},10000)
}
}
}