• WebSocket真实项目总结


    websocket

    websocket是什么?

    websocket是一种网络通讯协议。 websocket 是HTML5开始提供的一种在单个TCP链接上进行全双工通讯的协议。

    为什么需要websocket?

    初次接触websocket,都会带着疑惑去学习,既然已经有了HTTP协议,为什么还需要另一个协议?它能带来什么好处呢?很简单,因为HTTP协议的通讯只能由客户端发起。
    举列来说,我想了解今天的天气,只能是客户端向服务端发出请求,服务器返回查询结果,HTTP协议做不到服务器主动向客户端推送信息。

    为什么需要websocket

    传统的HTTP协议是无状态的,每次请求request都要由客户端浏览器主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据了这种客户端是主动方,服务端是被动方的传统web模式,对于信息变化不频繁的web应用来说造成的麻烦较小,而对于涉及实时信息的web应用却带来了很大的不方便,如带有即时通信,实时数据,订阅推送等功能的应用。

    为什么需要websocket

    websocket的优势

    相对于传统HTTP每次请求-应答都需要客户端与服务端简历连接的模式,websocket是类似socket的TCP长连接通讯模式,一旦websocket连接建立后,后继数据都已帧序列的形式传输,在客户端断开websocket连接活Server端终端连接前,不需要客户端和服务端重新发起连接请求,在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息实在同一个持久连接上发起,实时性优势明显。

    websocket实现方式

    websocket需要像TCP一样,先建立连接,需要客户端和服务端进行握手连接,连接成功后才能湘湖通信。

    websocket构造函数

    websocket对象作为一个构造函数,用于新建websocket实例

    var ws = new webSocket("ws://127.0.0.1:8090")
    
    • 1

    执行上面语句之后,客户端就会与服务器进行连接。

    webSocket.readyState

    readyState属性返回实例对象的当前状态,共有四种。

    CONNECTING:值为0,表示正在连接。
    OPEN:值为1,标识连接成功,可以通信了。
    CLOSING:值为2,标识连接正在关闭。
    CLOSED:值为3,标识连接已经关闭,或者打开链接失败。

    webSocket.onerror

    连接发生错误的回调方法

    ws.onerror = function(){
    	alert("webSocket连接发生错误“)
    }
    
    • 1
    • 2
    • 3

    webSocket.onclose

    实例对象的onclose 属性,用于指定关闭连接后的回调函数

    ws.onclose = function(){
    	alert("websocket连接关闭")
    }
    
    • 1
    • 2
    • 3

    webSocket.send()

    实例对象的send()方法用于向服务器发送数据

    ws.send("your message")
    
    • 1

    总结完webSocket如何握手及其所有的方法,下面进入实战

    使用websocket实现图表数据动态实时更新

    websocket 封装的websocket.js代码
    /* WebSocket封装
     * @param url: WebSocket接口地址与携带参数必填
     * @param onOpenFunc: WebSocket的onopen回调函数,如果不需要可传null
     * @param onMessageFunc: WebSocket的onmessage回调函数,如果不需要可传null
     * @param onCloseFunc: WebSocket的onclose回调函数,如果不需要可传null
     * @param onErrorFunc: WebSocket的onerror回调函数,如果不需要可传null
     * @param heartMessage: 发送后台的心跳包参数,必填 (给服务端的心跳包就是定期给服务端发送消息)
     * @param timer: 给后台传送心跳包的间隔时间,不传时使用默认值3000毫秒
     * @param isReconnect: 是否断掉立即重连,不传true时不重连
     */
    function useWebSocket(
        url,
        onOpenFunc,
        onMessageFunc,
        onCloseFunc,
        onErrorFunc,
        heartMessage,
        timer,
        isReconnect
      ) {
        let isConnected = false; // 设定已链接webSocket标记
        // websocket对象
        let ws = null;
        // 创建并链接webSocket
        let connect = () => {
          // 如果未链接webSocket,则创建一个新的webSocket
          if (!isConnected) {
            ws = new WebSocket(url);
            isConnected = true;
          }
        };
        // 向后台发送心跳消息
        let heartCheck = () => {
          // for (let i = 0; i < heartMessage.length; i++) {
          //   ws.send(JSON.stringify(heartMessage[i]))
          // }
        };
        // 初始化事件回调函数
        let initEventHandle = () => {
          ws.addEventListener('open', (e) => {
            console.log('onopen', e);
            // 给后台发心跳请求,在onmessage中取得消息则说明链接正常
            //heartCheck()
            // 如果传入了函数,执行onOpenFunc
            if (!onOpenFunc) {
              return false;
            } else {
              onOpenFunc(e, ws);
            }
          });
          ws.addEventListener('message', (e) => {
            // 接收到任何后台消息都说明当前连接是正常的
            if (!e) {
              console.log('get nothing from service');
              return false;
            } else {
              // 如果获取到后台消息,则timer毫秒后再次发起心跳请求给后台,检测是否断连
              setTimeout(
                () => {
                  if (isConnected) {
                    heartCheck();
                  }
                },
                !timer ? 3000 : timer
              );
            }
            // 如果传入了函数,执行onMessageFunc
            if (!onMessageFunc) {
              return false;
            } else {
              onMessageFunc(e);
            }
          });
          ws.addEventListener('close', (e) => {
            console.log('onclose', e);
            // 如果传入了函数,执行onCloseFunc
            if (!onCloseFunc) {
              return false;
            } else {
              onCloseFunc(e);
            }
            // if (isReconnect) { // 如果断开立即重连标志为true
            //   // 重新链接webSocket
            //   connect()
            // }
          });
          ws.addEventListener('error', (e) => {
            console.log('onerror', e);
            // 如果传入了函数,执行onErrorFunc
            if (!onErrorFunc) {
              return false;
            } else {
              onErrorFunc(e);
            }
            if (isReconnect) {
              // 如果断开立即重连标志为true
              // 重新链接webSocket
              connect();
            }
          });
        };
        // 初始化webSocket
        // (() => {
        // 1.创建并链接webSocket
        connect();
        // 2.初始化事件回调函数
        initEventHandle();
        // 3.返回是否已连接
        return ws;
        // })()
      }
      
      export default {
        useWebSocket,
      };
      
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118

    调用方法并建立连接使用:(当连接失败后,进行websocket重连)

    initWebSocket() {
          if(!this.ws) {
          	// url
            let url = 'ws://XXX.XXX.XXX.XXX:4002/websocket/11111'
            this.ws = websocket.useWebSocket(
              url,	// url
              this.wsOnOpen, // 链接回调
              this.wsOnMessage,	// 连接成功后处理接口返回信息
              this.wsOnClose, // 关闭回调
              this.wsOnError, // 消息通知错误回调
              [], // 发送后台的心跳包参数
              null, // 给后台传送心跳包的间隔时间
              true, // 是否断掉立即重连
            );
          }
        },
        wsOnOpen() {
          console.log('开始连接')
        },
        wsOnError(e) {
          console.log(e,'消息通知错误回调,重新连接')
          this.ws.close();
          this.ws = null;
          this.initWebSocket();
        },
        wsOnMessage(e) {
          if(e.data != '连接成功') {
    		    console.log(JSON.parse(e.data),'接口返回信息')
          }
        },
        wsOnClose() {
          console.log('关闭')
          // 意外关闭之后重新连接
          if(!this.disConnectTimer) {
            this.disConnectTimer = setTimeout(() => {
              this.initWebSocket()
              this.disConnectTimer = null
            }, 10000)
          }
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    实现效果:
    websocket实时图表
    重连效果
    websocket关闭重连效果
    完结~

  • 相关阅读:
    langchain中的Document类
    MYSQL——JBDC实现增删改查
    Spring Cloud之服务熔断与降级(Hystrix)
    shell if else 使用
    SAP MTS/ATO/MTO/ETO专题之九:M+M模式前后台操作,策略用50,提前准备原材料和半成品
    一份最基础的gitlab-ci文件,其中就maven的build和test
    消息队列选型方案
    神经网络做预测的原理,神经网络预测空气质量
    网络层总结(未完待续)
    postman调试注意事项
  • 原文地址:https://blog.csdn.net/qq_42696432/article/details/134392374