为什么要有websocket 如何使用 伪服务器推 HTTP定时轮询 长轮询 (笔记)

大部分网页功能场景是 HTTP请求 服务器返回HTTP响应

但仍然存在需要服务器主动发消息,客户端接收的情况
问题的关键在于:如何在用户不主动进行操作的情况下,网页主动接收数据并及时发生变更

有以下常见解决方案:

1.伪服务器推:

利用HTTP定时轮询,定时发送HTTP请求到服务器

  • 优点:
    用户无感知且成本极低
  • 缺点:
    用户概率感知明显卡顿,且会占用带宽且增加下游服务器负担

在这里插入图片描述

2.长轮询:

将HTTP请求超时设置的很大,在较长时间内等待服务器响应,例如百度网盘的扫码登录就是用的这种长轮询机制

  • 优点:
    用户无感知且响应及时,同时成本极低
  • 缺点:
    仍然会占用带宽且增加下游服务器负担,且本质还是客户端主动请求数据没有整整解决问题,只能用于简单场景
    在这里插入图片描述

3.websocket:

以上两种方法本质还是客户端主动请求数据 只能使用扫码等简单场景。
为应付网页游戏,网页聊天,网页协同办公等复杂场景,websocket协议应运而生。

TCP是全双工协议,通信两端都可以主动向对方发送数据。
HTTP1.1基于TCP协议,但只支持同一时间段的单向通信,也就是半双工。
websocket协议同样基于TCP,在HTTP的基础上使用。若某一页面需要用到websocket,则需要在HTTP请求中带上特殊的header:
connection:Upgrade 客户端想要升级通信协议
Upgrade:websocket 升级为websocket
Sec-WebSocket-Key随机base64码 用于协议升级转换后的通信验证

  • 优点:
    基本解决了客户端需要与服务器频繁交互的大部分场景
  • 缺点:
    增加了系统的开发维护成本,服务器长期维护长连接的性能消耗不小,且各个浏览器支持程度不一。
    在这里插入图片描述

如何使用

    initWebSocket () {
    
     
       if ('WebSocket' in window) {
    
    
         this.websock = new WebSocket(`ws:${
      
      process.env.projectConfig.websockApi}`);//这个连接ws://固定,后面的根据自己的IP和端口进行改变,我设置监听的就是8081
      }
				this.websock.onmessage = this.websocketonmessage
				this.websock.onerror = this.websocketonerror
				this.websock.onopen = this.websocketonopen
				this.websock.onclose = this.websocketclose


    },
    websocketonopen () {
    
     //
      console.log('连接成功');
      this.websock.send({
    
    });
      this.timer = window.setInterval(()=>{
    
     //每隔5秒钟发送一次心跳,避免websocket连接因超时而自动断开
        console.log('每隔5秒钟发送一次心跳');
        this.websock.send({
    
    });
      },5000);
    },
    websocketonerror () {
    
     //连接错误
      console.log( 'WebSocket连接失败')
      this.error_action() //自动重连
    },
    websocketonmessage (e) {
    
     // 数据接收
      console.log('接收到消息,准备xxxx',e);
      let data = JSON.parse(e.data)
      //xxx的功能代码
    },
    websocketclose (e) {
    
      // 关闭连接
      console.log('已关闭连接', e)
      this.error_action() //自动重连
    },
    error_action(){
    
    
      console.log('重新连接');
      clearInterval(this.timer);
      this.chonglian_action();
    },
    chonglian_action() {
    
    //重连方法
        //判断有没有网 此处代码后加的,为了优化没网实例化socket时候的报错问题
        if(!navigator.onLine){
    
    
          return ;//没网就中断
			  }
        //readyState 0尚未建立连接 1连接已经建立 2连接正在关闭 3连接已经关闭或不可用
        // if(this.websock.readyState==0||this.websock.readyState==3){
    
    
            this.initWebSocket()
            console.log('开始重新连接');
        // }
    }
  },
  destroyed () {
    
    
			this.websock.close() // 页面销毁后断开websocket连接
  }

猜你喜欢

转载自blog.csdn.net/Beatingworldline/article/details/128813137