当前位置:   article > 正文

websocket 使用方法和步骤详解_websocket使用

websocket使用

websocket使用步骤及相关解析


一、步骤及相关解析

1.确定需要开启并连接websocket的条件 ,以下简称ws

mounted() {
    //确定本地是否存入用户id   (如果有,代表用户已登入系统)
    let userInfo = JSON.parse(localStorage.getItem("userInfo"));
    this.id = userInfo.id;
    if (this.id) {
      this.initSocket();
    }
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ps: 确定本地是否存入用户id (如果有,代表用户已登入系统)


2.确定需要开启并连接websocket的条件

// 2.确定用户浏览器是否支持WebSocket 
    initSocket() {
      if ("WebSocket" in window) {
        // let tcp = location.protocol === 'https:' ? 'wss:' : 'ws:';

        // 2-1.如果已有ws开启,先关闭一次  进行我们自己的配置
        this.ws && this.ws.close();

        // 2-2.生产环境和非生产环境的协议配置  主要变量为 project 和 uid
        if(process.env.VUE_APP_TITLE === "stage"){
          this.wsUrl = `ws://test.ws.chiefgr.com/?project=jd-shop&uid=` + this.id;
        }else{
          this.wsUrl = 'ws://ws.chiefgr.com/?project=jd-shop&uid=' + this.id;
        }
        // 2-3. 配置一个我们对应的ws  new WebSocket(this.wsUrl);
        this.initWebSocket();
      } else {
        this.$notify({
          message: "当前浏览器不支持消息通知,请升级或更换浏览器!",
          position: "bottom-right",
          duration: 5000
        });
      }
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

ps: 判断用户浏览器是否支持ws,若支持,则进行我们需要的相关配置。


注:以下是ws事件方法:
// ws事件方法  
    initWebSocket() {
      this.ws = new WebSocket(this.wsUrl);  
      this.ws.onopen = this.wsOpen;  //连接建立时触发
      this.ws.onmessage = this.wsMessage; //客户端接收服务端数据时触发
      this.ws.onerror = this.wsError; //通信发生错误时触发
      this.ws.onclose = this.wsClose;  //连接关闭时触发
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

先把完整代码贴上来 后面有时间再整理步骤解析,代码里的解析其实已经挺详细了

最后:完整代码流程

import { exportDownload } from "@/api/user";

export default {
  data() {
    return {
      wsUrl: "",
      id: "",
      token: "",
      ws: "", //建立的连接
      lockReconnect: false, //是否真正建立连接
      timeout: 45 * 1000, //30秒一次心跳
      timeoutObj: null, //心跳心跳倒计时
      serverTimeoutObj: null, //心跳倒计时
      timeoutnum: null, //断开 重连倒计时

      notificationStatus: false, // 系统通知
    }
  },
  created() {
    this.notifyMeAuth();
  },
  mounted() {
    // 1. 确定本地是否存入用户id   
    let userInfo = JSON.parse(localStorage.getItem("userInfo"));
    this.id = userInfo.id;
    if (this.id) {
      // 1-1. 如果存在,代表用户已登入系统  开启连接websocket(下面简称ws)
      this.initSocket();
    }
  },
  beforeDestroy() {
    this.id = "";
    this.timeoutnum && clearTimeout(this.timeoutnum);
    this.timeoutObj && clearTimeout(this.timeoutObj);
    this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
    this.ws && this.ws.close();
  },
  methods: {
    // 2.确定用户浏览器是否支持WebSocket 
    initSocket() {
      if ("WebSocket" in window) {
        // let tcp = location.protocol === 'https:' ? 'wss:' : 'ws:';

        // 2-1.如果已有ws开启,先关闭一次  进行我们自己的配置
        this.ws && this.ws.close();

        // 2-2.生产环境和非生产环境的协议配置  主要变量为 project 和 uid
        if(process.env.VUE_APP_TITLE === "stage"){
          this.wsUrl = `ws://test.ws.chiefgr.com/?project=jd-shop&uid=` + this.id;
        }else{
          this.wsUrl = 'ws://ws.chiefgr.com/?project=jd-shop&uid=' + this.id;
        }
        // 2-3. 配置一个我们对应的ws  new WebSocket(this.wsUrl);
        this.initWebSocket();
      } else {
        this.$notify({
          message: "当前浏览器不支持消息通知,请升级或更换浏览器!",
          position: "bottom-right",
          duration: 5000
        });
      }
    },

    // ws事件方法  
    initWebSocket() {
      this.ws = new WebSocket(this.wsUrl);  
      this.ws.onopen = this.wsOpen;  //连接建立时触发
      this.ws.onmessage = this.wsMessage; //客户端接收服务端数据时触发
      this.ws.onerror = this.wsError; //通信发生错误时触发
      this.ws.onclose = this.wsClose;  //连接关闭时触发
    },

    
    //重置心跳
    reset() {
      //清除时间
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
      //重启心跳
      this.start();
    },

    // 3.连接成功,发一个心跳给服务器 表示我们已准备好
    wsOpen() {
      console.log("连接 成功", new Date());
      // this.wsSend();
      // 开启心跳
      this.start();
    },

    //开启心跳
    start() {
      var that = this;
      that.timeoutObj && clearTimeout(that.timeoutObj);
      that.serverTimeoutObj && clearTimeout(that.serverTimeoutObj);
      that.timeoutObj = setTimeout(function() {
        //3-1.这里发送一个心跳,后端收到后,返回一个心跳消息,
        if (that.ws.readyState == 1) { //readyState  == 1 :连接已建立,可以通信
          //如果连接正常  后端返回了信息,进入 6.数据接收
          that.ws.send("heartCheck");
        } else {
          //否则重连   //readyState  == 0 :连接尚未建立;  2:连接正在关闭; 3:连接已经关闭或不能打开
          that.reconnect();
        }
        // 3-2.发送心跳超时,则关闭ws  
        that.serverTimeoutObj = setTimeout(function() {
          //超时关闭  如果用户处于登录状态,则重连ws
          that.ws.close();
        }, that.timeout);
      }, that.timeout);
    },

    // 6.数据接收
    wsMessage(res) {
      let data = JSON.parse(res.data);
      let dom = "";
      // 根据返回的数据 判定是下载  还是消息通知  或者其他  (自行约定)
      if (data.title) {
        this.$store.dispatch("informLog/setNew", true);
        if (data.type == "App\\Notifications\\ExportReady") {
          // 6-1.下载  调下载接口exportDownload
          dom = `<div>${data.filename}</div>`;
          let newData = {
            filename: data.filename
          };
          exportDownload(newData)
            .then(res => {
              let name = data.filename;
              let url = window.URL.createObjectURL(res.data);
              let link = document.createElement("a");
              link.style.display = "none";
              link.href = url;
              link.setAttribute("download", name);
              document.body.appendChild(link);
              link.click();
            })
            .catch(() => {
              this.$notify.error("下载错误");
            });
        } else {
           // 6-2.其他通知
          dom = data.content;
          let text = "";
          if (data.content) {
            text = data.content.replace(/<.*?>/g, "");
          }
          // 发送桌面通知
          this.notifyMe({
            title: data.title,
            msg: text
          });
        }
        // 7.接收到数据之后  (不管是哪种类型,在系统中调起弹窗发送通知)
        this.$notify({
          title: data.title,
          dangerouslyUseHTMLString: true,
          message: dom,
          position: "bottom-right",
          duration: 15000
        });
      }

      // 8.收到服务器信息,心跳重置 {"code":2,"api_version":"1.12.4"}
      if (data.code == 2) {
        this.reset();
      }
    },
    // 发送消息
    wsSend() {
      this.ws.send(
        JSON.stringify({
          id: window.btoa(this.id)
        })
      );
    },

    // 4.关闭   
    wsClose() {
      console.log("连接 关闭", new Date());
      //4-1.  用户处于登录状态,重连ws
      if (this.id) {
        this.reconnect();
      }
    },
    // 错误
    wsError(err) {
      console.log("连接 错误", new Date());
      //重连
      this.reconnect();
    },

    // 5.重连ws
    reconnect() {
      //重新连接
      var that = this;
      if (that.lockReconnect) {
        return;
      }
      that.lockReconnect = true;
      //没连接上会一直重连,设置延迟避免请求过多
      that.timeoutnum && clearTimeout(that.timeoutnum);
      that.timeoutnum = setTimeout(function() {
        //新连接
        that.initWebSocket();
        that.lockReconnect = false;
      }, 5000);
    },

    // 系统 获取通知授权
    notifyMeAuth() {
      let that = this;
      // 先检查浏览器是否支持
      if (!("Notification" in window)) {
        if(!this.ddEvn){
          alert("此浏览器不支持桌面通知");
        }
      }

      // 检查用户是否同意接受通知
      else if (Notification.permission === "granted") {
        that.notificationStatus = true;
      }

      // 否则我们需要向用户获取权限
      // else if (Notification.permission !== 'denied')
      else {
        Notification.requestPermission(function(permission) {
          // 如果用户同意,就可以向他们发送通知
          if (permission === "granted") {
            that.notificationStatus = true;
          }
        });
      }
    },
    // 系统 通知
    notifyMe(obj) {
      if (this.notificationStatus) {
        let { title, msg } = obj;
        new Notification(title, {
          body: msg
        });
      }
    }
  }
}

  • 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
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号