灏天阁

js 端 websocket

· Yin灏
//webSocket 服务端地址
var wsUrl = "";
//webSocket 对象
var ws;
//webSocket 尝试重新创建webSocket 定时
var reconnectTimeOut;
//心跳重试次数  服务端3次无响应就断开重连
var heartCheckNum = 0;
//webSocket 链接锁,用来保证只有一个客户端与服务端只生成一个连接。
var lockReconnect = false;
//webSocket 关闭的类型 1默认。 2息屏关闭
var closeWsType = 1;
//判断浏览器支持
if ("WebSocket" in window) {
  console.log("支持WebSocket");
} else {
  alert("该浏览器不支持WebSocket");
}
//创建webSocket
var createWebSocket = function (wsUrl) {
  //console.log(wsUrl)
  try {
    //初始化webSocket连接
    ws = new WebSocket(wsUrl);
    webSocketInit();
  } catch (e) {
    //失败
    alert("createWebSocket catch", [e]);
    //尝试webSocket重连
    lockReconnect = false;
    webSocketReconnect(wsUrl);
  }
};
//初始化webSocket连接,成功后执行
var webSocketInit = function () {
  //断开webSocket连接成功触发事件
  ws.onclose = function (event) {
    //alert("连接已关闭。。。");
    //尝试webSocket重连
    lockReconnect = false;
    webSocketReconnect(wsUrl);
  };
  //发生错误时执行的回调函数
  ws.onerror = function (event) {
    //alert("连接错误。。。", [event]);
    //尝试webSocket重连
    lockReconnect = false;
    webSocketReconnect(wsUrl);
  };
  //连接建立成功,发送信息
  ws.onopen = function (event) {
    //例如
    var message = "连接websocket成功!";
    console.log(message);
    ws.send(message);

    //心跳检测启动
    heartCheck.start();
  };
  //收到来自服务端的消息时被调用
  ws.onmessage = function (event) {
    //let date = new Date();
    //let newdate = date.toLocaleString('chinese', {hour12: false});   //获取24小时制,中国时间,打印出   2019/01/03/  08:40:32
    //console.log("接收到 WebSocket消息:", [event, newdate]);
    //var data=json.parse(event);
    //处理你的业务
    //处理你的业务
    //处理你的业务
    //处理你的业务

    if (event.data == "1") {
      heartCheckNum = 0;
      //console.log("接收到服务端的心跳回应:", event.data);
    } else {
      //处理收到的消息
      //alert("消息:"+JSON.stringify(event.data))
    }
    //接收一次后台推送的消息,即进行一次心跳检测重置
    heartCheck.reset();
  };
};

//webSocket重试
var webSocketReconnect = function (url) {
  console.log("webSocket 连接断开,正在尝试重新建立连接。。。");
  if (closeWsType == 2) {
    return;
  }
  if (lockReconnect) {
    return;
  }
  lockReconnect = true;
  heartCheckNum = 0;
  heartCheck.stop();
  //js中清楚setTimeout的定时触发设置,之所以加个timer,是为了方便第二次赋值给timer。
  //也就是说直接clearTImeout(timer)则timer就不存在了 再次访问就是error了。
  //而timer&&clearTimeout(timer)则将timer 变成undefined
  reconnectTimeOut && clearTimeout(reconnectTimeOut);
  reconnectTimeOut = setTimeout(function () {
    createWebSocket(url);
  }, 4000);
};

/*
 *心跳检测:
 *发送方按照一定规则(周期性发送、空闲发送等等)向接收方发送固定格式的消息,接受方收到消息后回复一个固定格式的消息 ,
 *如果长时间没有收到,则认为当前连接失效,将其断开。
 *注:发送方可以是客户端或者服务端,根据实际情况而定,常见是客户端作为发送方。
 *webSocket一般是间隔90秒内无操作会自动断开,因此,需要加入一个心跳机制,以防止ws断开
 *这里为3秒,倒计时3秒内无操作则进行一次访问,有操作则重置计时器。
 */
var heartCheck = {
  timeout: 3000, //3秒
  timeoutObj: null,
  reset: function () {
    //接收成功一次推送,就将心跳检测的倒计时重置为30秒
    clearTimeout(this.timeoutObj); //重置倒计时
    this.start();
  },
  start: function () {
    //启动心跳检测机制,设置倒计时30秒一次
    this.timeoutObj = setTimeout(function () {
      //console.log("webSocket  心跳。。。" + heartCheckNum);
      //心跳
      //与服务端定制ping pong,客户端发送0,服务端回应1 服务端三次没回应 就断开重连
      if (heartCheckNum === 3) {
        //关闭链接  链接断开以后就会自动重试,所以不需要其他处理
        ws.close();
      } else {
        //readyState 表示连接状态,可以是以下值:
        //0 - 表示连接尚未建立。
        //1 - 表示连接已建立,可以进行通信。
        //2 - 表示连接正在进行关闭。
        //3 - 表示连接已经关闭或者连接不能打开。
        //if (ws.readyState === 1) {
        //}
        ws.send("0");
        heartCheckNum++;
      }
      heartCheck.reset();
    }, this.timeout);
  },
  stop: function () {
    //接收成功一次推送,就将心跳检测的倒计时重置为30秒
    clearTimeout(this.timeoutObj); //重置倒计时
  },
  //onopen连接上,就开始start及时,如果在定时时间范围内,onmessage获取到了服务端消息,
  //就重置reset倒计时,距离上次从后端获取消息30秒后,执行心跳检测,看是不是断了。
};
//监听浏览器关闭 断开ws
window.onbeforeunload = function () {
  if (ws) {
    ws.close();
  }
};
window.addEventListener(
  "pagehide",
  function (e) {
    if (ws) {
      ws.close();
      closeWsType = 2;
    }
  },
  false
);
document.addEventListener("visibilitychange", function () {
  // 用户息屏、或者切到后台运行 (离开页面)
  if (document.hidden) {
    if (ws) {
      ws.close();
      closeWsType = 2;
    }
  } else {
    closeWsType = 1;
    if (ws.readyState === 1) {
    } else {
      //息屏打开重连
      createWebSocket(wsUrl);
    }
  }
});
//开始创建webSocket连接
createWebSocket(wsUrl);

- Book Lists -