使用vue3简单实现WebSocket通信

06-01 1038阅读

WebSocket是一种在客户端和服务器之间进行双向通信的网络协议。它通过建立持久性的、全双工的连接,允许服务器主动向客户端发送数据,而不需要客户端显式地发送请求。

关于WebSocket通信的简单介绍:

  1. 握手阶段:在建立WebSocket连接之前,客户端需要发送一个HTTP请求到服务器,请求升级为WebSocket协议。这个过程称为握手(Handshake)。如果服务器支持WebSocket协议,它将返回带有特定标头的HTTP响应,表示握手成功。
  2. 建立连接:客户端收到服务器的握手响应后,会重新建立连接。此时,连接将从HTTP协议切换到WebSocket协议,并保持打开状态。这样就建立了可持续的双向通信通道。
  3. 数据传输:一旦WebSocket连接建立,客户端和服务器可以开始互相发送消息。客户端和服务器都可以通过发送文本或二进制数据来通信。消息可以是简单的字符串,也可以是复杂的数据结构,如JSON对象等。
  4. 断开连接:当需要关闭WebSocket连接时,客户端或服务器可以主动发送一个关闭帧来断开连接。收到关闭帧的一方会结束连接并发送回应帧,完成连接的关闭。

WebSocket通信具有以下特点:

  • 实时性:由于WebSocket使用长连接,可以实时地将数据推送到客户端,而不需要显式地发送请求。这使得它非常适合需要快速、实时响应的应用程序。
  • 双向通信:WebSocket允许客户端和服务器之间双向传输消息。这意味着服务器可以主动向客户端推送数据,而不仅限于响应客户端的请求。
  • 较低的开销:相比于传统的轮询方式(每隔一段时间发送请求),WebSocket连接具有较低的开销。一旦建立连接,它只需要发送少量的数据头部信息,并且在保持连接时可以重复使用该连接。
  • 跨平台支持:WebSocket协议是一种标准化的协议,被广泛支持和应用于不同的平台和编程语言中。

    通过使用WebSocket,开发人员可以实现实时通信、聊天应用、多人游戏、股票行情等需要及时交互和更新的应用程序。

    1.相关代码如下:

    ①创建src/utils/websocket.ts文件

    import { ElMessage } from 'element-plus'
    import store from '../store'
    let websocket: WebSocket | null = null; // 用于存储实例化后websocket
    let rec: any; // 断线重连后,延迟5秒重新创建WebSocket连接  rec用来存储延迟请求的代码
    // 创建websocket
    function creatWebSocket(wsUrl: string) {
      console.log("websocket==================");
      // 判断当前浏览器是否支持WebSocket
      if ("WebSocket" in window) {
        console.log("当前浏览器支持 WebSocket");
      } else if ("MozWebSocket" in window) {
        console.log("当前浏览器支持 MozWebSocket");
      } else {
        console.log("当前浏览器不支持 WebSocket");
      }
      try {
        initWebSocket(wsUrl); // 初始化websocket连接
      } catch (e) {
        console.log("尝试创建连接失败");
        reConnect(wsUrl); // 如果无法连接上 webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接
      }
    }
    // 初始化websocket
    function initWebSocket(wsUrl: string) {
      websocket = new WebSocket(wsUrl);
      console.log("websocket:", websocket);
      websocket.onopen = function () {
        websocketOpen();
      };
      //   // 接收
      websocket.onmessage = function (e: MessageEvent) {
        websocketonmessage(e);
      };
      // 连接发生错误
      websocket.onerror = function () {
        console.log("WebSocket连接发生错误");
        //     isConnect = false; // 连接断开修改标识
        reConnect(wsUrl); // 连接错误 需要重连
      };
      websocket.onclose = function (e) {
        websocketclose(e);
      };
    }
    // 定义重连函数
    let reConnect = (wsUrl: string) => {
      console.log("尝试重新连接");
      if (store.state.isConnected) return; // 如果已经连上就不在重连了
      rec && clearTimeout(rec);
      rec = setTimeout(function () {
        // 延迟5秒重连  避免过多次过频繁请求重连
        creatWebSocket(wsUrl);
      }, 5000);
    };
    // 创建连接
    function websocketOpen() {
      console.log("连接成功");
      store.dispatch('connect'); // 修改连接状态
    }
    // 数据接收
    function websocketonmessage(e: MessageEvent) {
      console.log("数据接收", e.data);
      const data = JSON.parse(e.data);  // 解析JSON格式的数据
      // 下面的判断则是后台返回的接收到的数据  如何处理自己决定
      if (data.code === 400) {
        console.log("数据接收", data.msg);
        ElMessage({
          showClose: true,
          message: data.msg,
          type: 'warning',
        })
      } else if (data.code === 404) {
        ElMessage({
          showClose: true,
          message: data.msg,
          type: 'warning',
        })
      } else if (data.code === 0) {
        ElMessage({
          showClose: true,
          message: "连接成功",
          type: 'success',
        })
      } else if (data.code === 200) {
        ElMessage({
          showClose: true,
          message: data.msg,
          type: 'success',
        })
        // 成功后的相应处理  此处成功后播放音乐
        const audio = new Audio('./tipMusic.mp3');
        audio.play();
      } else {
        ElMessage({
          showClose: true,
          message: data.msg,
          type: 'error',
        })
        // 延时5秒后刷新页面
        setTimeout(() => {
          location.reload();
        }, 1000);
      }
      // let data = JSON.parse(decodeUnicode(e.data))
    }
    // 关闭
    function websocketclose(e: any) {
      console.log(e);
      store.dispatch('disconnect'); // 修改连接状态
      console.log("connection closed (" + e.code + ")");
    }
    // 数据发送
    function websocketsend(data: any) {
      console.log("发送的数据", data, JSON.stringify(data));
      if (websocket && store.state.isConnected) { // 检查连接状态
        websocket.send(JSON.stringify(data));
        
      } else {
        ElMessage({
          showClose: true,
          message: "请选择设备连接",
          type: 'error',
        })
      }
    }
    // 实际调用的方法==============
    // 发送
    function sendWebSocket(data: any) {
      // 如果未保持连接状态 不允许直接发送消息 提示请选择连接设备
      if (!store.state.isConnected) {
        ElMessage({
          showClose: true,
          message: "请选择设备连接",
          type: 'error',
        })
      } else {
        websocketsend(data);
        console.log("------------------");
        
      }
    }
    // 关闭
    let closeWebSocket = () => {
      if (websocket) {
        websocket.close();
        ElMessage({
          showClose: true,
          message: "设备已关闭",
          type: 'success',
        })
      }
    };
    export {
      initWebSocket,
      sendWebSocket,
      creatWebSocket,
      closeWebSocket,
    };

    ②全局保存连接状态src/store/index.ts

    先安装npm install vuex

    import { createStore } from 'vuex'
    const store = createStore({
      state: {
        isConnected: false,//连接状态
      },
      mutations: {
        setConnected(state: any, isConnected: boolean) {
          state.isConnected = isConnected
        },
      },
      actions: {
        connect({ commit }: { commit: any }) {
          // 连接成功后,将 isConnected 状态设置为 true
          commit('setConnected', true)
        },
        disconnect({ commit }: { commit: any }) {
          // 断开连接或退出登录时,将 isConnected 状态设置为 false
          commit('setConnected', false)
        }
      }
    })
    export default store
    

    ③页面连接设备

    import { ref ,onMounted} from 'vue'
    import { closeWebSocket,initWebSocket } from '../../utils/websocket'
    import { useStore } from 'vuex';
    const store = useStore()
    //连接设备  (具体路径和后端规定)
    function connectMsg() {
      const toIp = `ws://192.168.50.50:8822/websocket/ipad/${roomId.value}`;
      store.dispatch('connect')
      initWebSocket(toIp)
    }
    // 设备断开
    function closeWs() {
      closeWebSocket()
      store.dispatch('disconnect')
    }
    

              连接设备

            关闭设备

           

    ④发送消息给后端

    import {ref} from 'vue'

    使用vue3简单实现WebSocket通信
    (图片来源网络,侵删)

    import { sendWebSocket } from '../../utils/websocket'

    const courseTopic = ref('')

    使用vue3简单实现WebSocket通信
    (图片来源网络,侵删)

    const courseGrowth = ref('')

    const todayHaul = ref('')

    使用vue3简单实现WebSocket通信
    (图片来源网络,侵删)

    const selectedTeacher = ref('')

    //提交

    const harvestSubmit = () => {

      // 要发送的数据  和后端定义格式

      const harvestData = {

        "HandlerType": "COURSEREFLECT",

        "topicReflect": courseTopic.value,

        "growReflect": courseGrowth.value,

        "harvest": todayHaul.value,

        "teacher": "李老师"

    }

        console.log("提交反思与收获数据",harvestData); 

      // 发送消息给后端

        sendWebSocket(harvestData)

      

      }

           

             

    课程反思

           

           

           

    今日收获

           

           

           

                提交

             

       

    欢迎大家批评指正 谢谢 ~~

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码