websocket通信
看同事大佬封装的websocket,在这里记录一下,温故而知新,增加websocket.ts(websocket连接、失败、关闭操作文件),control.ts(发布订阅模式操作文件),index.ts
- websocket.ts
1 import EventListenControl from './control'//引入发布订阅模式 2 import {basePath,port,baseIp,webport} from '@/config/ip.config' 3 const defaultURL = "ws://127.0.0.1:3006/ws";//websocket连接地址 4 interface PrepareRequest { 5 key: string; 6 val:any; 7 } 8 //定义websocket类 9 class Ws extends EventListenControl { 10 url = "";//websocket地址 11 ws: WebSocket | null = null;//websocket 12 connected = false;//判断是否连接成功 13 pending = false;//判断是否在连接中 14 prepareList: PrepareRequest[] = [];//请求队列中的消息 15 heartbeat: any = null;//判断是否已经存在请求通道 16 loginApi: string;//登录api验证登录 17 constructor(loginApi?: string, url = defaultURL) { 18 super(); 19 this.url = url; 20 this.loginApi = "";//默认没有使用接口验证 21 } 22 connect(params?: string) {//params传入的当前用户id 23 setTimeout(() => { 24 if (this.pending) return; 25 this.pending = true; 26 this.destroy(); 27 const url = this.url + (params ? '?id='+params : "");//判断params传入的当前用户id,存在就拼在地址后传入 28 try { 29 let ws = new WebSocket(url); 30 this.ws = ws; 31 ws.onmessage = (event) => {//接收消息,收到消息后将消息广播出去(发布) 32 if (this.connected) { 33 let data = JSON.parse(event.data); 34 this.emit(data.key, data.val);//通过key来制定发布消息 35 } 36 } 37 ws.onopen = (e) => { 38 this.onconnect(e); 39 this.connected = true; 40 this.pending = false; 41 } 42 ws.onclose = e => { 43 if (ws === this.ws) { 44 this.pending = false; 45 this.connected = false; 46 } 47 } 48 ws.onerror = (e) => { 49 console.log('onerror执行error事件,开始重连'); 50 } 51 } catch (error) { 52 console.log(error); 53 } 54 }, 200) 55 } 56 postmessage(key : string, val: Object) { 57 if (this.ws && this.connected) {//判断当前请求队列是否在使用或者websocket是否连接失败,如果失败就将消息先存到队列中, 58 const dataString = JSON.stringify({ 59 key, 60 val, 61 }) 62 this.ws.send(dataString); 63 } else { 64 this.prepareList.push({ key,val }); 65 } 66 } 67 destroy() { 68 if (this.ws) { 69 this.ws.close(); 70 } 71 if (this.heartbeat) { 72 clearInterval(this.heartbeat); 73 this.heartbeat = null; 74 } 75 } 76 onconnect(e: Event) { 77 if (!this.heartbeat) { 78 this.heartbeat = setInterval(() => { 79 this.postmessage("heartbeat", "ping"); 80 }, 1000 * 60 * 2); 81 } 82 this.afterConnect(e); 83 } 84 afterConnect(e: Event) { } 85 } 86 87 const createWebsocket = (loginApi?: string,) => { 88 let ws = new Ws();//可传入接口,也可不传入,传入接口为需要验证的接口 89 return ws; 90 } 91 92 export { 93 createWebsocket, 94 }; 95 96 export default Ws;
- control.ts
class EventListenControl { container: any = {}; on(evt: string, callback: Function) {//订阅时,将对应方法和key值存储在container中 if (!this.container[evt]) this.container[evt] = []; this.container[evt].push(callback); } emit(evt: string, ...arg: any[]) {//发布时,会去container中通过传入evt即key值来查找,找到后将数据传入订阅写的回调中 if (this.container.hasOwnProperty(evt)) this.container[evt].forEach((fn: Function) => { fn(...arg); }) } remove(evt: string, callback: Function) {//删除container中的订阅方法 if (this.container[evt] && this.container[evt] instanceof Array) { let idx = this.container[evt].findIndex((el: Function) => el == callback); if (idx >= 0) { this.container[evt].splice(idx, 1); } } } } export default EventListenControl;
- index.ts
import { createWebsocket } from './websocket' const ws = createWebsocket(); ws.onconnect = (e) => {}; export default ws;
- vue3组件中调动,
在test.vue组件中引入index.ts
(1.)连接websocket
<template> </template> <script lang="ts" setup> import { ref,onMounted } from "vue"; import ws from './websocket/index' onMounted(()=>{ ws.connect("123456465");//连接websocket,123456465为当前用户id }) </script> <style lang="less" scoped> </style>
(2.)订阅
<template> </template> <script lang="ts" setup> import { ref,onMounted } from "vue"; import ws from './websocket/index' //消息接收 const handleReceiveMessage = (res: any) => { console.log(res,"接收到的消息") }; ws.on("lalala", handleReceiveMessage); </script> <style lang="less" scoped> </style>
(3.)发布
<script lang="ts" setup> import { ref,onMounted } from "vue"; import ws from './websocket/index' ws.emit("lalala","你好,请问你叫什么名字"); </script>
(4.)删除
<script lang="ts" setup> import { ref,onMounted } from "vue"; import ws from './websocket/index' ws.remove("lalala"); </script>
这是我在使用中用到的一些方法,对于其中的接口校验认证我还没有操作过,所以没有在这里记录。