148 lines
4.6 KiB
JavaScript
148 lines
4.6 KiB
JavaScript
|
||
import { reactive, ref } from 'vue';
|
||
// WebSocket 工具类,封装了 WebSocket 的连接、发送、接收、心跳、重连和关闭等操作
|
||
class WebsocketUtil {
|
||
|
||
// 构造函数,初始化 WebSocket 连接
|
||
constructor(url, time, params) {
|
||
this.url = url; // WebSocket 服务器的 URL
|
||
this.params = params; // WebSocket 服务器的 URL
|
||
this.time = time; // 心跳发送的间隔时间(秒)
|
||
this.socketTask = null; // WebSocket 任务对象
|
||
this.isOpen = false; // WebSocket 连接是否打开
|
||
this.reconnectTimeout = null; // 重连定时器
|
||
this.heartbeatInterval = null; // 心跳定时器
|
||
this.messageCallbacks = []; // 存储外部注册的消息回调函数的数组
|
||
this.messageCallbacks = []; // 存储外部注册的消息回调函数的数组
|
||
|
||
// 初始化 WebSocket 连接
|
||
this.initializeWebSocket();
|
||
}
|
||
|
||
// 初始化 WebSocket 连接
|
||
initializeWebSocket() {
|
||
if( this.isOpen){
|
||
return
|
||
}
|
||
this.socketTask = uni.connectSocket({
|
||
url: this.url,
|
||
success: () => {
|
||
console.log('WebSocket连接成功');
|
||
return this.socketTask;
|
||
},
|
||
fail: (error) => {
|
||
console.error('WebSocket连接失败', error);
|
||
this.reconnect();
|
||
}
|
||
});
|
||
|
||
this.socketTask.onOpen((res) => {
|
||
console.log('WebSocket连接正常!==',res);
|
||
this.isOpen = true;
|
||
// 连接成功后启动心跳和消息监听
|
||
this.startHeartbeat();
|
||
this.listenForMessages();
|
||
|
||
});
|
||
this.socketTask.onError((res) => {
|
||
console.log('WebSocket连接失败!==',res);
|
||
this.reconnect();
|
||
});
|
||
// 注意:这里的 onClose 监听器应该放在 uni.connectSocket 调用之后
|
||
this.socketTask.onClose((result) => {
|
||
this.isOpen = false;
|
||
// if( this.isOpen ){
|
||
this.reconnect();
|
||
// }
|
||
});
|
||
|
||
}
|
||
|
||
// 启动心跳检测
|
||
startHeartbeat() {
|
||
if (this.heartbeatInterval) {
|
||
clearInterval(this.heartbeatInterval);
|
||
}
|
||
this.heartbeatInterval = setInterval(() => {
|
||
if (this.isOpen) {
|
||
this.send(JSON.stringify({"type": "ping_interval"}));
|
||
}
|
||
}, this.time);
|
||
}
|
||
|
||
// 发送消息
|
||
send(data,type) {
|
||
if (this.socketTask && this.isOpen) {
|
||
this.socketTask.send({
|
||
data: data,
|
||
success: (res) => {
|
||
// console.log('消息发送成功', res);
|
||
},
|
||
fail: (error) => {
|
||
console.error('消息发送失败', error);
|
||
this.reconnect(); // 这里可能需要根据实际情况判断是否重连
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
// 监听 WebSocket 消息
|
||
listenForMessages() {
|
||
if (this.socketTask) {
|
||
this.socketTask.onMessage((res) =>{
|
||
const { data } = res;
|
||
this.messageCallbacks.forEach(callback => callback(data.toString())); // 假设 data 是字符串或可转换为字符串
|
||
});
|
||
this.send("WebSocket连接正常");
|
||
} 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) {
|
||
this.messageCallbacks.push(callback);
|
||
}
|
||
|
||
// 外部注销消息回调函数
|
||
offMessage(callback) {
|
||
this.messageCallbacks = []
|
||
}
|
||
|
||
// 销毁 WebSocket 连接,清理资源
|
||
destroy() {
|
||
this.closeSocket();
|
||
clearInterval(this.heartbeatInterval);
|
||
clearTimeout(this.reconnectTimeout);
|
||
this.messageCallbacks = [];
|
||
}
|
||
}
|
||
|
||
export default WebsocketUtil;
|