244 lines
6.1 KiB
TypeScript
244 lines
6.1 KiB
TypeScript
import { error } from "../../uni_modules/uview-plus";
|
|
|
|
// import qs from "qs";
|
|
const qs = {
|
|
stringify: (obj) => {
|
|
const str= Object.keys(obj).reduce((prve, key) => {
|
|
return prve + `${key}=${obj[key]}&`
|
|
}, '?')
|
|
|
|
return str.substring(0,str.length-1)
|
|
}
|
|
}
|
|
function ElMessage() {
|
|
|
|
}
|
|
function ElMessageBox() {
|
|
|
|
}
|
|
|
|
const user = {
|
|
userInfo: {
|
|
shopId: ''
|
|
}
|
|
}
|
|
|
|
export interface ApifoxModel {
|
|
account : string;
|
|
operate_type : string;
|
|
shop_id : string;
|
|
table_code ?: string;
|
|
type : string;
|
|
[property : string] : string | number | undefined; // 限制额外属性类型
|
|
}
|
|
|
|
export type msgType = 'add' | 'reduce' | 'remove' | 'edit' | 'init' | 'cleanup' | 'del' | 'rottable' | 'batch' | 'disconnect' | 'clearOrder';
|
|
|
|
class WebSocketManager {
|
|
private client : WebSocket | null = null;
|
|
private connected : boolean = false;
|
|
private shop_id = user.userInfo.shopId ? String(user.userInfo.shopId) : '';
|
|
private autoConnect : boolean = true;
|
|
private initParams : ApifoxModel = {
|
|
type: 'shopping',
|
|
account: this.shop_id || '', // 提供默认值
|
|
operate_type: 'init',
|
|
table_code: '',
|
|
shop_id: this.shop_id || '', // 提供默认值
|
|
};
|
|
private onMessage : (message : any) => void = () => { };
|
|
private messageHandlers : Map<string, ((message : string) => void)[]> = new Map();
|
|
private type : string = 'shopping';
|
|
private reconnectAttempts = 0;
|
|
private maxReconnectAttempts = Infinity; // 自定义最大重试次数
|
|
private reconnectDelay = 5000; // 重试延迟(单位:毫秒)
|
|
private timer : any | null = null;
|
|
private reconnectTimer : any | null = null
|
|
|
|
connectSocketSuccsss(){
|
|
if(!this.client){
|
|
return
|
|
}
|
|
this.client.onOpen(() => {
|
|
this.connected = true;
|
|
console.log("WebSocket 连接已建立");
|
|
console.log(this.initParams);
|
|
this.sendMessage(this.initParams);
|
|
this.clearTimer();
|
|
this.timer = setInterval(() => {
|
|
this.sendMessage({ type: "ping_interval", set: 'shopping' }, false);
|
|
}, 1000 * 10);
|
|
})
|
|
|
|
this.client.onClose(() => {
|
|
this.clearTimer();
|
|
this.connected = false;
|
|
console.log("WebSocket 连接已断开");
|
|
if (this.autoConnect) {
|
|
this.reconnect(); // 自动重连
|
|
}
|
|
})
|
|
|
|
this.client.onError((error : Event) => {
|
|
this.clearTimer();
|
|
console.error("WebSocket 发生错误:", error);
|
|
this.reconnect(); // 自动重连
|
|
})
|
|
|
|
this.client.onMessage((event : MessageEvent) => {
|
|
try {
|
|
const message = JSON.parse(event.data);
|
|
if (message && message.msg_id) {
|
|
this.onMessageHandler({ msg_id: message.msg_id });
|
|
}
|
|
this.onMessage(message);
|
|
} catch (e) {
|
|
console.error("消息解析失败:", e);
|
|
}
|
|
})
|
|
}
|
|
|
|
// 初始化 WebSocket 客户端
|
|
setupWebSocket() {
|
|
// #ifdef H5
|
|
const endpoint = "http://192.168.1.31:2348/"
|
|
// #endif
|
|
|
|
// #ifdef MP-WEIXIN
|
|
const endpoint = "ws://192.168.1.31:2348/"
|
|
// #endif
|
|
|
|
if (!endpoint) {
|
|
console.warn("WebSocket 已被禁用,请在配置文件中配置 VITE_APP_WS_ENDPOINT");
|
|
return;
|
|
}
|
|
|
|
if (this.client && this.connected) {
|
|
console.log("客户端已存在并且连接正常");
|
|
return this.client;
|
|
}
|
|
|
|
const url = qs.stringify(this.initParams);
|
|
// this.client = new WebSocket(endpoint + '?' + url);
|
|
|
|
|
|
|
|
this.client = uni.connectSocket({
|
|
url: endpoint + url,
|
|
success: (res) => {
|
|
console.log('连接成功');
|
|
},
|
|
fail: (err) => {
|
|
console.error(error(err))
|
|
console.error('WebSocket 连接失败,尝试重连');
|
|
}
|
|
});
|
|
this.connectSocketSuccsss()
|
|
console.log('this.client');
|
|
console.log(this.client);
|
|
}
|
|
|
|
// 消息回执
|
|
public onMessageHandler(data : any) {
|
|
if (this.client && this.connected) {
|
|
this.client.send({data:JSON.stringify({ ...data, type: 'receipt' })});
|
|
}
|
|
}
|
|
|
|
// 订阅主题
|
|
public subscribeToTopic(initParams : ApifoxModel, onMessage : (message : any) => void) {
|
|
console.log(`正在订阅主题: `, initParams);
|
|
this.initParams = { ...this.initParams, ...initParams };
|
|
this.disconnect();
|
|
this.setupWebSocket();
|
|
this.onMessage = onMessage;
|
|
this.autoConnect = true
|
|
}
|
|
|
|
public sendMessage(message : any, isSendInitParams : boolean = true) {
|
|
if (!this.client || !this.connected) {
|
|
// ElMessage.error('发送失败,已重新连接,请重新操作');
|
|
this.reconnect();
|
|
return;
|
|
}
|
|
if (message.operate_type == 'disconnect') {
|
|
this.disconnect();
|
|
return
|
|
}
|
|
const msg = JSON.stringify(isSendInitParams ? { ...this.initParams, ...message } : message);
|
|
|
|
try {
|
|
this.client?.send({data:msg});
|
|
} catch (error) {
|
|
console.error("发送消息失败:", error);
|
|
// ElMessage.error('发送失败,已重新连接,请重新操作');
|
|
this.reconnect();
|
|
}
|
|
}
|
|
|
|
public canSendMessage() {
|
|
return this.client && this.connected;
|
|
}
|
|
|
|
// 断开 WebSocket 连接
|
|
public disconnect() {
|
|
if (this.client && this.connected) {
|
|
console.log("断开 WebSocket 连接");
|
|
this.clearTimer();
|
|
try {
|
|
if(this.client){
|
|
this.client.closeSocket();
|
|
}
|
|
} catch (error) {
|
|
//TODO handle the exception
|
|
console.error('关闭WebSocket连接失败')
|
|
}
|
|
|
|
this.client = null;
|
|
this.connected = false;
|
|
this.autoConnect = false;
|
|
}
|
|
}
|
|
// 自动重连机制
|
|
private reconnect() {
|
|
if (!this.autoConnect) {
|
|
return;
|
|
}
|
|
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
this.reconnectAttempts++;
|
|
console.log(`尝试第 ${this.reconnectAttempts} 次重连...`);
|
|
this.reconnectTimer = setTimeout(() => {
|
|
this.setupWebSocket();
|
|
}, this.reconnectDelay);
|
|
} else {
|
|
clearTimeout(this.reconnectTimer);
|
|
console.error("达到最大重连次数,停止重连");
|
|
ElMessageBox.confirm('达到最大重连次数' + this.maxReconnectAttempts + '次,已停止重连,是否立即重连?', '提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
|
|
callback: (action : string) => {
|
|
console.log(action);
|
|
if (action == 'confirm') {
|
|
this.setupWebSocket();
|
|
this.reconnectAttempts = 0;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// 清除定时器
|
|
private clearTimer() {
|
|
if (this.timer) {
|
|
clearInterval(this.timer);
|
|
this.timer = null;
|
|
}
|
|
if (this.reconnectTimer) {
|
|
clearInterval(this.reconnectTimer);
|
|
this.reconnectTimer = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
export default new WebSocketManager(); |