之前以为websocket复杂,想使用插件来实现,查了一番资料,原生写法就很简单。

项目需求

查询列表,需要实时获取员工上报的数据

代码部分

Table.vue

<script setup lang="ts">
import { ref, onUnmounted } from "vue";
//页面卸载,关闭socket
onUnmounted(() => {
  closeWebSocket();
});
//这里后端接口需要用登录的用户id,通过session获取
const userInfo = getSessStorage("userInfo") as { userId: string };
// WebSocket
const ws = ref();
const initWebSocket = () => {
  ws.value = new WebSocket(`ws://${location.host}/commonSocket/${userInfo.userId}`);
  ws.value.onopen = () => {
    console.log("连接成功");
  };
  //后端设置心跳,会每间隔一定时间,触发一次,根据内容变化处理逻辑
  ws.value.onmessage = (e: any) => {
    console.log(e, "广播返回的消息");
    //后端约定了,如果返回字符串“UPDATE”,就更新表格
    if (e.data === "UPDATE") {
      //getTable();
    }
  };
  ws.value.onerror = () => {
    console.log("连接错误");
    //断连后每5秒重连一次
    setTimeout(() => {
      initWebSocket();
    }, 5000);
  };
};
initWebSocket();
//关闭链接(在页面销毁时销毁连接)
const closeWebSocket = () => {
  ws.value.close();
};
</script>

因为跨域问题,这里使用了vite的proxy代理功能

vite.config.ts

import { defineConfig} from "vite";
import { resolve } from "path";
……

export default defineConfig(({ command }) => {
  return {
    resolve: {
      alias: {
        "@": resolve(__dirname, "src")
      },
      extensions: [".js", ".json", ".ts"], 
    },
    plugins: [
      vue(),
    ],
    
    server: {
      host: "0.0.0.0",
      port: 3000,
      proxy: {
        "/commonSocket": {
          // target: 'ws://192.168.0.66:60601/',这是后端接口地址
          target: 'ws://192.168.0.66:60601/',
          changeOrigin: true,
          ws: true
        },
      },
    },
  };
});


如果代理设置好,连接成功,以上websocket会打印"连接成功"和输出返回。

完!

补充:

项目运行了一段,对websocket有了更多了解:
websocket保持连接,在网络中断时候,不会报错,短时间恢复网络,还会继续连接上,长时间还未知。

解决办法:

加入一个前端检测机制,每次心跳,后端发送当前时间戳,前端接收保存变量里,用定时器间隔检查时间戳,和当前时间做比较,发现时间间隔大于一定,比如10分钟,说明有一段没收到心跳,就认为断连了,重新初始化websocket

Logo

前往低代码交流专区

更多推荐