You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.1 KiB
161 lines
4.1 KiB
function pickJsonObj(value) {
|
|
try {
|
|
return JSON.parse(value)
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
class WebSocketClient {
|
|
constructor(url) {
|
|
this.url = url;
|
|
this.socket = null;
|
|
this.isReconnecting = false;
|
|
this.reconnectInterval = 3000; // 重连间隔,单位毫秒
|
|
this.heartBeatInterval = 5000; // 心跳间隔,单位毫秒
|
|
this.pingTimeoutDuration = 1000; // 超过这个时间,后端没有返回pong,则判定后端断线了。
|
|
this.heartBeatTimer = null;
|
|
this.destroy = false; // 是否销毁
|
|
}
|
|
|
|
connect() {
|
|
this.socket = uni.connectSocket({
|
|
url: this.url,
|
|
complete: () => { }
|
|
});
|
|
this.initEventListeners();
|
|
}
|
|
|
|
initEventListeners() {
|
|
this.socket.onOpen(() => {
|
|
// WebSocket连接已打开
|
|
this.onConnected();
|
|
this.startHeartBeat();
|
|
});
|
|
|
|
this.socket.onMessage((res) => {
|
|
const obj = pickJsonObj(res.data);
|
|
if (obj.type === 'pong') {
|
|
// 收到pong消息,心跳正常,无需处理
|
|
this.resetPingTimeout(); // 重置计时
|
|
} else {
|
|
// 处理其他消息
|
|
this.onMessage(res.data);
|
|
}
|
|
});
|
|
|
|
this.socket.onClose((res) => {
|
|
// WebSocket连接已关闭
|
|
if (this.destroy) {
|
|
this.onClosed()
|
|
return;
|
|
}
|
|
this.stopHeartBeat();
|
|
if (!this.isReconnecting) {
|
|
this.reconnect();
|
|
}
|
|
});
|
|
}
|
|
|
|
sendMessage(message) {
|
|
if (this.socket) {
|
|
this.socket.send({
|
|
data: message
|
|
});
|
|
}
|
|
}
|
|
|
|
onMessage(message) {
|
|
// 处理收到的消息
|
|
console.log('message:', message)
|
|
}
|
|
|
|
startHeartBeat() {
|
|
this.heartBeatTimer = setInterval(() => {
|
|
this.sendMessage(JSON.stringify({
|
|
type: 'ping'
|
|
})); // 发送ping消息
|
|
this.pingTimeout = setTimeout(() => {
|
|
// 未收到pong消息,尝试重连...
|
|
this.reconnect();
|
|
}, this.pingTimeoutDuration);
|
|
}, this.heartBeatInterval);
|
|
}
|
|
|
|
stopHeartBeat() {
|
|
if (this.heartBeatTimer) {
|
|
clearInterval(this.heartBeatTimer);
|
|
}
|
|
}
|
|
|
|
reconnect() {
|
|
this.isReconnecting = true;
|
|
setTimeout(() => {
|
|
this.onReconnect();
|
|
this.connect();
|
|
this.isReconnecting = false;
|
|
}, this.reconnectInterval);
|
|
}
|
|
|
|
resetPingTimeout() {
|
|
clearTimeout(this.pingTimeout); // 重置计时
|
|
}
|
|
|
|
close() {
|
|
this.destroy = true;
|
|
this.stopHeartBeat();
|
|
if (this.socket) {
|
|
this.socket.close();
|
|
this.socket = null;
|
|
}
|
|
}
|
|
/**
|
|
* 重连时触发
|
|
*/
|
|
onReconnect() {
|
|
console.log('尝试重连...')
|
|
}
|
|
/**
|
|
* 连接成功时触发
|
|
*/
|
|
onConnected() {
|
|
console.log('WebSocket连接已打开');
|
|
}
|
|
/**
|
|
* 断开时触发
|
|
*/
|
|
onClosed() {
|
|
console.log('已断开连接')
|
|
}
|
|
}
|
|
|
|
export default WebSocketClient;
|
|
|
|
// websocket 使用
|
|
// import WebSocketClient from '@/utils/websocket.js'
|
|
// // 创建WebSocket实例
|
|
// ws.value = new WebSocketClient('ws://这里填写你的服务地址');
|
|
// // 连接WebSocket
|
|
// ws.value.connect();
|
|
// // 接收消息时触发
|
|
// ws.value.onMessage = (value) => {
|
|
// const obj = JSON.parse(value)
|
|
// if (obj.type === 'message') {
|
|
// list.value.push({
|
|
// time: new Date().toLocaleString(),
|
|
// value: obj.value
|
|
// })
|
|
// }
|
|
// }
|
|
// // 重连时触发
|
|
// ws.value.onReconnect = () => {
|
|
// netStatus.value = 2;
|
|
// }
|
|
// // 连接成功后触发
|
|
// ws.value.onConnected = () => {
|
|
// netStatus.value = 1;
|
|
// }
|
|
// // 关闭后触发(直接销毁了,不会继续重连)
|
|
// ws.value.onClosed = () => {
|
|
// netStatus.value = 0;
|
|
// }
|
|
|