需求/功能
- 使用websocket能够监听服务端发送的数据并处理
- 能够注册监听事件
- 能够监听webSocket断开
- 全局只用到一个websocket对象,可多页面复用
设计思路
- 封装websocket类,并使用单例模式,全局只有一个Websocket对象
- 使用 reconnecting-websocket 监听websocket连接与断开
设计实现
useWebsocket.js - JS版本
/*
* @Autor: pxt
* @Description: websocket类封装 需要先npn install reconnecting-websocket
使用 reconnecting-websocket 库 能够实现断线重连
* @Documentation: https://github.com/joewalnes/reconnecting-websocket
* @Date: 2022-08-01 17:59:44
* @LastEditTime: 2022-08-01 18:07:05
*/
import Rwebsocket from 'reconnecting-websocket';
class IWebsocket {
constructor() {
// 定义一个对象 用于接收websocket对象
this.instance = null;
}
// 创建连接
conectWebsocket(urlOut) {
// 对webSocket连接创建回调
return new Promise((resolve, reject) => {
let url = urlOut || 'ws://localhost:8666';
this.instance = new Rwebsocket(url);
this.instance.onopen = (evt) => {
console.log("websocket-连接成功", evt);
resolve(evt);
};
this.instance.onclose = (evt) => {
console.log("websocket-断开连接");
};
this.instance.onmessage = (evt) => {
this.onMessageHandler(evt);
};
this.instance.onerror = (evt) => {
// console.log(evt);
console.log("websocket-连接错误");
reject(evt);
};
});
}
//注册监听事件
resgisterHandler(cb) {
this.handler = cb;
}
// 清除注册事件
clearHandler() {
this.handler = () => { };
}
// 发送消息
sendMessageHandler(data) {
data = JSON.stringify(data);
this.instance?.send(data);
}
// 消息事件监听
onMessageHandler(evt) {
try {
const params = JSON.parse(evt.data);
this.handler?.call(this, params);
} catch (error) {
this.handler?.call(this, evt.data);
}
}
// 断开连接
close() {
this.instance?.close();
}
}
export default new IWebsocket();
useWebsocket.ts - TS版本
/*
* @Autor: pxt
* @Description: websocket类封装 需要先npn install reconnecting-websocket
使用 reconnecting-websocket 库 能够实现断线重连
* @Documentation: https://github.com/joewalnes/reconnecting-websocket
* @Date: 2022-07-28 17:47:54
* @LastEditTime: 2022-07-28 18:49:01
*/
import Rwebsocket from 'reconnecting-websocket'
class IWebsocket {
// 定义一个对象 用于接收websocket对象
public instance: Rwebsocket | null = null;
// wenbsocket数据处理注册事件
public handler?: (params: any) => void;
constructor() {}
// 创建连接
conectWebsocket(urlOut?: string) {
// 对webSocket连接创建回调
return new Promise((resolve, reject) => {
let url: string = urlOut || 'ws://localhost:8666';
this.instance = new Rwebsocket(url);
this.instance.onopen = (evt) => {
console.log("websocket-连接成功",evt);
resolve(evt);
};
this.instance.onclose = (evt) => {
console.log("websocket-断开连接");
};
this.instance.onmessage = (evt) => {
this.onMessageHandler(evt);
};
this.instance.onerror = (evt) => {
// console.log(evt);
console.log("websocket-连接错误");
reject(evt)
};
})
}
//注册监听事件
resgisterHandler(cb: (evt: MessageEvent<any>) => void) {
this.handler = cb;
}
// 清除注册事件
clearHandler() {
this.handler = () => {};
}
// 发送消息
sendMessageHandler(data: any) {
data = JSON.stringify(data);
this.instance?.send(data);
}
// 消息事件监听
onMessageHandler(evt: MessageEvent<any>) {
try {
const params = JSON.parse(evt.data);
this.handler?.call(this, params);
} catch (error) {
this.handler?.call(this, evt.data);
}
}
// 断开连接
close(){
this.instance?.close();
}
}
export default new IWebsocket();
项目使用
import IWebsocket from '@/utils/useWebsocket'
//连接WebSocket
function connect(){
IWebsocket.conectWebsocket().then(()=>{
console.log('连接成功')
}).catch(err =>{
console.log('连接失败',err);
});
}
//注册监听事件
function resgister(){
IWebsocket.resgisterHandler((str)=>{
console.log('服务返回的数据',str);
})
}
//给服务端发送数据
function sendData(){
IWebsocket.sendMessageHandler('你好');
}
总结
使用单例模式,全局只会生成一个websocket实例,可实现多页面复用。注册的监听事件由handler对象接收而不是使用数组方式,方便了监听当前显示页面,但造成无法多个地方同时监听,如果需要同时监听的可以改造成数组接收的方式,参考观察者模式。 reconnecting-websocket 代替了心跳函数编写,更加简单方便