如何使用vue3简单实现WebSocket通信
作者:前端爆炸虫
这篇文章主要给大家介绍了关于如何使用vue3简单实现WebSocket通信的相关资料,WebSocket是全双工网络通信通信协议,实现了客户端和服务器的平等对话,任何一方都可以主动发送数据,需要的朋友可以参考下
前言
WebSocket是一种在客户端和服务器之间进行双向通信的网络协议。它通过建立持久性的、全双工的连接,允许服务器主动向客户端发送数据,而不需要客户端显式地发送请求。
关于WebSocket通信的简单介绍:
- 握手阶段:在建立WebSocket连接之前,客户端需要发送一个HTTP请求到服务器,请求升级为WebSocket协议。这个过程称为握手(Handshake)。如果服务器支持WebSocket协议,它将返回带有特定标头的HTTP响应,表示握手成功。
- 建立连接:客户端收到服务器的握手响应后,会重新建立连接。此时,连接将从HTTP协议切换到WebSocket协议,并保持打开状态。这样就建立了可持续的双向通信通道。
- 数据传输:一旦WebSocket连接建立,客户端和服务器可以开始互相发送消息。客户端和服务器都可以通过发送文本或二进制数据来通信。消息可以是简单的字符串,也可以是复杂的数据结构,如JSON对象等。
- 断开连接:当需要关闭WebSocket连接时,客户端或服务器可以主动发送一个关闭帧来断开连接。收到关闭帧的一方会结束连接并发送回应帧,完成连接的关闭。
WebSocket通信具有以下特点:
- 实时性:由于WebSocket使用长连接,可以实时地将数据推送到客户端,而不需要显式地发送请求。这使得它非常适合需要快速、实时响应的应用程序。
- 双向通信:WebSocket允许客户端和服务器之间双向传输消息。这意味着服务器可以主动向客户端推送数据,而不仅限于响应客户端的请求。
- 较低的开销:相比于传统的轮询方式(每隔一段时间发送请求),WebSocket连接具有较低的开销。一旦建立连接,它只需要发送少量的数据头部信息,并且在保持连接时可以重复使用该连接。
- 跨平台支持:WebSocket协议是一种标准化的协议,被广泛支持和应用于不同的平台和编程语言中。
通过使用WebSocket,开发人员可以实现实时通信、聊天应用、多人游戏、股票行情等需要及时交互和更新的应用程序。
相关代码如下:
①创建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<any>) { 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<any>) { 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
③页面连接设备
<script setup lang="ts"> 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') } </script>
<template> <div class="connect"> <el-button class="elbtn" @click="connectMsg">连接设备</el-button> <el-button class="elbtn" @click="closeWs">关闭设备</el-button> </div> </template>
④发送消息给后端
<script setup lang="ts"> import {ref} from 'vue' import { sendWebSocket } from '../../utils/websocket' const courseTopic = ref('') const courseGrowth = ref('') const todayHaul = ref('') const selectedTeacher = ref('') //提交 const harvestSubmit = () => { // 要发送的数据 和后端定义格式 const harvestData = { "HandlerType": "COURSEREFLECT", "topicReflect": courseTopic.value, "growReflect": courseGrowth.value, "harvest": todayHaul.value, "teacher": "李老师" } console.log("提交反思与收获数据",harvestData); // 发送消息给后端 sendWebSocket(harvestData) } </script> <template> <div class="think"> <p>课程反思</p> <el-input v-model="courseTopic" :rows="3" type="textarea" placeholder="主题课程" /> <el-input v-model="courseGrowth" :rows="3" type="textarea" placeholder="适性成长课程" /> <p>今日收获</p> <el-input v-model="todayHaul" :rows="3" type="textarea" /> </div> <div class="btn"> <button @click="harvestSubmit"> 提交</button> </div> </template>
总结
到此这篇关于如何使用vue3简单实现WebSocket通信的文章就介绍到这了,更多相关vue3实现WebSocket通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!