vue3+ts+uniapp&webSocket封装
·
1.创建文件webSocket.ts(我创建的路径@/utils/webSocket.ts)
// webSocket.ts
let WSS_SERVER_URL ="wss://后端给的链接"
type WebSocketUrl = string;
interface WebSocketMessage {
state: number;
method: string;
}
interface SendMessageOptions {
data: string;
}
interface CloseSocketOptions {
reason?: string;
success?: () => void;
fail?: (err: any) => void;
}
class webSocketClass {
private url: WebSocketUrl | string;
private data: WebSocketMessage | null = null;
private isCreate: boolean = false; // WebSocket 是否创建成功
private isConnect: boolean = false; // 是否已经连接
private isInitiative: boolean = false; // 是否主动断开
private timeoutNumber: number; // 心跳检测间隔(秒)
private heartbeatTimer: ReturnType<typeof setInterval> | null = null; // 心跳检测定时器
private reconnectTimer: ReturnType<typeof setTimeout> | null = null; // 断线重连定时器
private socketExamples: UniNamespace.SocketTask | null = null; // websocket实例
private againTime: number; // 重连等待时间(单位秒)&&金价刷新时间
private timeOut: boolean = false; // 是否连接超时
constructor(url: string = WSS_SERVER_URL, time: number = 60) {
this.url = url;
this.timeoutNumber = time;
this.againTime = 1;
this.initSocket();
}
// 初始化websocket连接
public initSocket(): void {
try {
this.socketExamples = uni.connectSocket({
url: this.url,
success: () => {
this.isCreate = true;
},
fail: () => {
this.isCreate = false;
},
});
this.createSocket();
} catch (error) {
}
}
// 创建websocket连接
private createSocket(): void {
if (this.isCreate && this.socketExamples) {
// 监听 WebSocket 连接打开事件
try {
this.socketExamples.onOpen(() => {
this.isConnect = true;
if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
// 打开心跳检测(根据项目需求,可自行决定是否启用心跳检测)
// this.heartbeatCheck();
});
// 监听 WebSocket 接受到服务器的消息事件
this.socketExamples.onMessage((res) => {
const data = JSON.parse(res.data);
uni.$emit("marketUpdate", data);
});
// 监听 WebSocket 连接关闭事件
this.socketExamples.onClose(() => {
this.isConnect = false;
this.reconnect();
});
// 监听 WebSocket 错误事件
this.socketExamples.onError((res) => {
this.timeOut =
res.errMsg.includes("Timed") || res.errMsg.includes("Invalid HTTP");
});
} catch (error) {
console.warn(error);
}
} else {
console.warn("WebSocket 初始化失败!");
}
}
// 发送消息
public sendMsg(value: WebSocketMessage): Promise<boolean> {
const param = JSON.stringify(value);
return new Promise((resolve, reject) => {
if (!this.socketExamples) {
reject(new Error("WebSocket 实例未初始化"));
return;
}
this.socketExamples.send({
data: param,
success() {
resolve(true);
},
fail(error) {
reject(error);
},
});
});
}
// 开启心跳检测
private heartbeatCheck(): void {
this.data = {
state: 1,
method: "heartbeat",
};
this.heartbeatTimer = setInterval(() => {
if (this.data) {
this.sendMsg(this.data);
}
}, this.timeoutNumber * 1000);
}
// 重新连接
private reconnect(): void {
// 停止发送心跳
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
// 如果不是人为关闭的话,进行重连
if (!this.isInitiative) {
this.reconnectTimer = setTimeout(() => {
this.initSocket();
}, this.againTime * 1000);
}
}
public setIsInitiativeFalse(): void {
this.isInitiative = false;
}
public setIsInitiativeTrue(): void {
this.isInitiative = true;
}
// 关闭 WebSocket 连接
public closeSocket(reason: string = "关闭"): void {
if (this.socketExamples) {
this.socketExamples.close({
reason,
success: () => {
this.data = null;
this.isCreate = false;
this.isConnect = false;
this.isInitiative = true;
this.socketExamples = null;
if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
},
fail: (err) => {
},
});
}
}
}
export default webSocketClass;
2.使用
在入口文件APP.vue中引入并创建实例,连接websocket
<script setup lang="ts">
const websocketUtil = new WebsocketUtil(); // 创建 WebSocket 工具类实例
provide("websocketUtil", websocketUtil); // 提供给所有子组件
</script>
在需要的页面使用
<script setup lang="ts">
let websocketUtil = inject("websocketUtil");
onShow(() => {
// 接收后端数据
uni.$on("onMessage", (data) => {
//业务逻辑
});
});
//使用websocket给后端发送信息
function sendMsg(){
websocketUtil.sendMsg(params);
}
</script>
更多推荐



所有评论(0)