一、代码封装
// WebSocket 工具类,封装了 WebSocket 的连接、发送、接收、心跳、重连和关闭等操作
class WebsocketUtil {
// WebSocket 服务器的 URL
url: string;
// 心跳发送的间隔时间(秒)
time: number;
// WebSocket 任务对象
socketTask: any;
// WebSocket 连接是否打开
isOpen: boolean;
// 重连定时器
reconnectTimeout: NodeJS.Timeout | null;
// 心跳定时器
heartbeatInterval: NodeJS.Timeout | null;
// 存储外部注册的消息回调函数的数组
messageCallbacks: Array<(data: string) => void>;
// 构造函数,初始化 WebSocket 连接
constructor(url: string, time: number) {
this.url = url;
this.time = time;
this.socketTask = null;
this.isOpen = false;
this.reconnectTimeout = null;
this.heartbeatInterval = null;
this.messageCallbacks = [];
// 初始化 WebSocket 连接
this.initializeWebSocket();
}
// 初始化 WebSocket 连接
initializeWebSocket() {
this.socketTask = uni.connectSocket({
url: this.url,
success: () => {
console.log('WebSocket连接成功');
this.isOpen = true;
// 连接成功后启动心跳和消息监听
this.startHeartbeat();
this.listenForMessages();
},
fail: (error) => {
console.error('WebSocket连接失败', error);
this.reconnect();
}
});
// 注意:这里的 onClose 监听器应该放在 uni.connectSocket 调用之后
this.socketTask.onClose((result: any) => {
this.isOpen = false;
this.reconnect();
});
}
// 启动心跳检测
startHeartbeat() {
if (this.heartbeatInterval) {
clearInterval(this.heartbeatInterval);
}
this.heartbeatInterval = setInterval(() => {
if (this.isOpen) {
this.send('ping');
}
}, this.time * 1000);
}
// 发送消息
send(data: string) {
if (this.socketTask && this.isOpen) {
this.socketTask.send({
data: data,
success: (res: any) => {
console.log('消息发送成功', res);
},
fail: (error: any) => {
console.error('消息发送失败', error);
this.reconnect(); // 这里可能需要根据实际情况判断是否重连
}
});
}
}
// 监听 WebSocket 消息
listenForMessages() {
if (this.socketTask) {
this.socketTask.onMessage((res: { data: any }) => {
const { data } = res;
this.messageCallbacks.forEach(callback => callback(data.toString())); // 假设 data 是字符串或可转换为字符串
});
} else {
console.error('WebSocket 连接尚未建立,无法监听消息');
}
}
// 重连 WebSocket
reconnect() {
if (this.reconnectTimeout) {
clearTimeout(this.reconnectTimeout);
}
this.reconnectTimeout = setTimeout(() => {
this.initializeWebSocket();
}, 3000);
}
// 关闭 WebSocket 连接
closeSocket() {
if (this.socketTask) {
uni.closeSocket({
success: () => {
console.log('WebSocket连接已关闭');
this.isOpen = false;
},
fail: (error) => {
console.error('关闭WebSocket连接失败', error);
}
});
this.socketTask = null;
}
}
// 外部注册消息回调函数
onMessage(callback: (data: string) => void) {
this.messageCallbacks.push(callback);
}
// 外部注销消息回调函数
offMessage(callback: (data: string) => void) {
this.messageCallbacks = this.messageCallbacks.filter(cb => cb !== callback);
}
// 销毁 WebSocket 连接,清理资源
destroy() {
this.closeSocket();
clearInterval(this.heartbeatInterval);
clearTimeout(this.reconnectTimeout);
this.messageCallbacks = [];
}
}
export default WebsocketUtil;
二、单页面使用
<template>
<div>
<!-- 你的组件模板 -->
</div>
</template>
<script setup>
import { ref, onUnmounted } from 'vue';
import WebsocketUtil from './WebsocketUtil';
const websocket = ref(null);
// 组件挂载时初始化WebSocket
onMounted(() => {
websocket.value = new WebsocketUtil('wss://your-websocket-url.com', 5);
// 可以注册消息回调
websocket.value.onMessage(data => {
console.log('Received data:', data);
});
});
// 组件卸载时清理WebSocket
onUnmounted(() => {
if (websocket.value) {
websocket.value.destroy();
}
});
</script>
二、全局使用
方法一、
1.在app.vue中
<template>
<div id="app">
<!-- 子组件 -->
</div>
</template>
<script setup>
import { provide } from 'vue';
import WebsocketUtil from './path/to/WebsocketUtil';
const websocketUtil = new WebsocketUtil('your-websocket-url', 5); // 创建 WebSocket 工具类实例
provide('websocketUtil', websocketUtil); // 提供给所有子组件
</script>
2.页面上调用
<script setup>
import { inject } from 'vue';
const websocketUtil = inject('websocketUtil'); // 注入 WebSocket 工具类实例
// 现在你可以使用 websocketUtil 来进行 WebSocket 通信了
websocketUtil.onMessage(data => {
console.log('Received data:', data);
});
</script>
方法二
在main.js中
//引入websocket文件
import wsRequest from './websocket.js'
//开启websocket
let websocket = new wsRequest("ws://xxx:you.are.url/connect/websocket",50)
//挂载到全局
Vue.prototype.$socket = websocket
方法三 vuex或者pinia
对于更复杂的状态管理,特别是当 WebSocket 的状态需要在多个组件之间共享时,使用 Vuex 或 Pinia 可能是更好的选择。你可以在这些状态管理库中创建一个模块来专门处理 WebSocket 连接和消息,大致的原理同上。