WebSocket 及其心跳检测和重连

本文主要说一下WebSocket的含义工作原理特点,用一个例子展示如何使用它,以及对它心跳检测重连

1. WebSocket 是个啥?
WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议(独立的、创建在 TCP 上的)。
2. 功能是什么?
使客户端和服务器之间数据交换变得更加简单,允许服务端主动向客户端推送数据。
3. 如何交互?
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
4. 为何会出现这个websocket协议?
网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询使浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,这样会浪费很多的带宽等资源。
5.  特点:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

6. 一颗栗子展示它当如何使用:

//订阅地址获取, 建立连接
 ajax({
            url: path,
            method: method,
}).then((res)=>{
          this.loadWebsocket(res.url);    
}).catch(() => {
            console.error('websocket连接失败');
 });


loadWebsocket=(url)=>{
         //(1)建立webSoctket通道
         if (window && 'WebSocket' in window) {
            this.webSocket = new WebSocket(`ws://${url}`);  // ws 统一资源标志符,类似于 HTTPS
         }
         //(2)  打开连接
        this.webSocket.onopen = () => {
            console.info('实时报警推送连接成功');
          /**
           * 心跳连接
           */
           if (this.state.heartBeatTimeOut === false) {
                if (this.heart) {
                    clearInterval(this.heart);
                    this.heart = null;
                }
                return;
            }
           // 防止定时器重复定义,先清除再定义
           if(this.heart){
                clearInterval(this.heart);
                this.heart= null;
           }
           this.heart = setInterval(function () {
                    try {
                        this.webSocket.send('heartbeat');
                    } catch (error) {
                        if(this.heart){
                            clearInterval(this.heart);
                        this.heart = null;
                    }
                }
            }, 30000);
         };
        // (3)收到消息
        this.webSocket.onmessage = (event) => {  //客户端接收服务端数据
               <div> 信息:{name},性别{sex},年龄{age}</div>  // 消息:小明,性别未知,年龄18

       }; 
       // 连接发生错误时
       this.webSocket.onerror = () => { //通信发生错误
            console.error('连接中断');
           //重新连接
            this.reconnect();
        };
        //关闭
        this.webSocket.onclose = (e) => {
            console.error('连接中断');
            //重新连接
            this.reconnect();
            //code为xx时,主动断开连接,不再重连
            if (e.code === xx) return;
        }

        reconnect=()=> {
                if(this.state.loopReconnect){
                    return;
               }
                this.setState({
                    loopReconnect: true
                });
               // 没连接上会一直重连,设置延迟避免请求过多
              if (this.reconnectTimeOut){
                    clearTimeout(this.reconnectTimeOut);
                    this.reconnectTimeOut = null;
               }
               this.reconnectTimeOut = setTimeout(function(){
                        this.loadWebsocket();
                        this.setState({
                                loopReconnect: false   //避免websocket重复连接
                        });
               }, 4000);
}


注:通道了都建立好了,互通信息就好了啊,为什么要加个心跳???
在使用websocket的过程中,有时候会遇到网络断开的情况,但在网络断开的时候服务器端并没有触发onclose的事件。
这样就导致:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失。
因此需要一种机制来检测客户端和服务端是否处于正常的链接状态。因此就有了websocket的心跳了。
即:每隔一段时间会向服务器发送一个数据包,告诉服务器自己还活着,同时客户端会确认服务器端是否还活着,如果还活着的话,就会回传一个数据包给客户端来确定服务器端也还活着,否则的话,有可能是网络断开连接了。需要重连~
现在先用一个定时器模拟推送一条信息,结果应是     消息:小明,性别未知,年龄18
let i = 0;
     setInterval(() => {
           this._setAlarmInfo([{
                id: 123,
                name: '小明',
                age: '18',
                sex: '未知'
           }]);
           i++;
      }, 10 * 1000);

参考资料:
https://www.ruanyifeng.com/blog/2017/05/websocket.html
https://www.runoob.com/html/html5-websocket.html
https://www.cnblogs.com/tugenhua0707/p/8648044.html

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值