blog icon indicating copy to clipboard operation
blog copied to clipboard

浅尝websocket

Open mtonhuang opened this issue 2 years ago • 1 comments

mtonhuang avatar Dec 27 '21 08:12 mtonhuang

前言

最近半年,重构了组内一个项目,主要技术栈为Vue全家桶 ,因为该项目的特殊性,有采集的功能,浏览器经常会跟服务器请求数据,在没有接手之前,项目里用了大量的 ajax轮询,不断地建立HTTP连接,然后等待服务端处理,很是被动,并不能满足日益复杂的业务场景,同样不利于代码的维护。

于是尝试接触websocket,重构了整个项目,虽然过程有诸多困难,但结果总是好的。

一、websocket是什么?

1、websocket是HTML5出的协议,为了解决 HTTP 本身无法解决的某些问题而做出的一个改良设计。

2、Websocket是一个持久化的协议(基于HTTP协议)。

3、Websocket只需要一次HTTP握手,整个通讯过程是建立在一次连接/状态中。

二、websocket用法

1、下载 vue-native-websocket

npm i vue-native-websocket

2、在main.js 中引入并且初始化 websocket


import VueNativeSock from "vue-native-websocket";

// base.lkWebSocket为你服务端websocket地址
Vue.use(VueNativeSock, "ws://xxxx", {
  // 启用Vuex集成,store的值为你的vuex
  store: store,
  // 数据发送/接收使用使用json格式
  format: "json",
  // 开启自动重连
  reconnection: true,
  // 尝试重连的次数
  reconnectionAttempts: 5,
  // 重连间隔时间
  reconnectionDelay: 1000
});

3、使用VUEx管理websocket状态

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
    state: {
        socket: {
            isConnected: false, // 连接状态
            message: "", // 消息内容
            reconnectError: false // 重新连接错误
        }
    },
    mutations: {
    SOCKET_ONOPEN(state, event) {
      // 连接打开触发的函数
      Vue.prototype.$socket = event.currentTarget;
      state.socket.isConnected = true;
      console.log("Connected");
    },
    SOCKET_ONCLOSE(state, event) {
      // 连接关闭触发的函数
      state.socket.isConnected = false;
      console.log("连接关闭触发");
    },
    SOCKET_ONERROR(state, event) {
      // 连接发生错误触发的函数
      console.error(state, event);
    },
    SOCKET_ONMESSAGE(state, message) {
      // 收到消息时触发的函数
      state.socket.message = message;
      // console.log(message);
    },
    SOCKET_RECONNECT(state, count) {
      // 重新连接触发的函数
      console.info(state, count);
    },
    SOCKET_RECONNECT_ERROR(state) {
      // 重新连接失败触发的函数
      state.socket.reconnectError = true;
    }
  }
})
export default store;

4、使用websocket

// xxx.vue
export default {
    name: 'xxx',
    data() {
        return{}
    },
    mounted() {
        // 监听消息接收
        this.$options.sockets.onmessage = (res) => {
        const that = this;
        const data = JSON.parse(res.data);
        let xxx = data.xxx;
        let result = data.result;
        if (result.code === 0) {
            switch (xxx) {
            case 'xxx':
                break;

            default:
                break;
            }
        } else {
            // 错误处理
        }
    }
  }
}

mtonhuang avatar Dec 27 '21 09:12 mtonhuang