基于UniApp.SocketTask的封装
约 434 字大约 1 分钟
2025-01-06
import { useAppStore } from '@/store';
type EventListener = (data: any) => void;
const { VITE_SOCKET_URL } = import.meta.env;
class SocketService {
private static instance: SocketService;
private listeners: Record<string, EventListener[]> = {};
private socketTask: UniApp.SocketTask | null = null;
private isConnected = false;
private constructor() {}
public static getInstance(): SocketService {
if (!SocketService.instance) {
SocketService.instance = new SocketService();
}
return SocketService.instance;
}
// 建立连接
public connect(url: string): Promise<void> {
return new Promise((resolve, reject) => {
if (this.isConnected) {
console.warn('WebSocket 已连接');
return resolve();
}
this.socketTask = uni.connectSocket({
url: `${url}&userId=${useAppStore().$state.userInfo.userId}`,
fail: (err) => {
console.log(err);
},
complete: () => {},
});
if (!this.socketTask) {
reject('socket连接失败');
}
this.socketTask.onOpen(() => {
console.log('WebSocket 连接成功');
this.isConnected = true;
resolve();
});
this.socketTask.onMessage((res) => {
this.handleMessage(res.data as string);
});
this.socketTask.onError((err) => {
console.error('WebSocket 连接失败:', err);
this.isConnected = false;
reject(err);
});
this.socketTask.onClose(() => {
console.log('WebSocket 已关闭');
this.isConnected = false;
this.connect(VITE_SOCKET_URL);
});
});
}
// 注册事件监听器
public on(eventName: string, listener: EventListener): void {
if (!this.listeners[eventName]) {
this.listeners[eventName] = [];
}
this.listeners[eventName].push(listener);
}
// 取消事件监听器
public off(eventName: string, listener: EventListener): void {
if (!this.listeners[eventName]) return;
this.listeners[eventName] = this.listeners[eventName].filter((l) => l !== listener);
}
// 触发事件监听器
private emit(eventName: string, data: any): void {
const listeners = this.listeners[eventName];
if (listeners && listeners.length > 0) {
listeners.forEach((listener) => listener(data));
} else {
console.warn(`无监听器处理事件: ${eventName}`);
}
}
// 处理接收到的消息
private handleMessage(data: string): void {
try {
if (data[0] === '0') return;
const bracketIndex = data.indexOf('[');
if (bracketIndex === -1) {
console.warn('数据格式不正确,忽略:', data);
return;
}
const jsonData = data.substring(bracketIndex);
const parsedArray = JSON.parse(jsonData);
if (!Array.isArray(parsedArray) || parsedArray.length < 2) {
console.error('数据格式不符合事件要求:', jsonData);
return;
}
const eventName = parsedArray[0];
const eventData = eventName === 'message' ? parsedArray[1] : JSON.parse(parsedArray[1]);
this.emit(eventName, eventData);
} catch (error) {
console.error('解析消息失败:', error, '数据:', data);
}
}
// 发送消息
public sendMessage(message: any): Promise<void> {
return new Promise((resolve, reject) => {
if (!this.isConnected || !this.socketTask) {
return reject(new Error('WebSocket 未连接'));
}
this.socketTask.send({
data: JSON.stringify(message),
success: () => {
console.log('消息发送成功');
resolve();
},
fail: (err) => {
console.error('消息发送失败', err);
reject(err);
},
});
});
}
// 监听消息
public onMessage(callback: (data: any) => void): void {
if (!this.socketTask) {
console.warn('WebSocket 未连接,无法监听消息');
return;
}
this.socketTask.onMessage((res) => {
callback(res.data);
});
}
// 关闭连接
public close(): void {
if (this.socketTask) {
this.socketTask.close({});
this.socketTask = null;
this.isConnected = false;
console.log('WebSocket 已手动关闭');
}
}
}
export default SocketService.getInstance();