uniapp封装uni-websocket

222 阅读2分钟

前言

uniapp自带的websocket直接使用会遇到重复建立连接的问题,同时无法获取我的globaldata,因此,在原有的基础上封装了一个简单的符合我需求的websocket.js,可以直接复制使用

封装websocket.js

class WebSocketClient {
    constructor() {
        this.ws = null;
        this.url = 'ws://yourURL'; // 替换成你的实际 WebSocket 服务器地址
        this.onMessage = null;
    }

    connect() {
        if (this.ws && this.ws.readyState === 1) {
            console.log('WebSocket已连接');
            return;
        }

        try {
            this.ws = uni.connectSocket({
                url: this.url,
                header: {
                    'content-type': 'application/json'
                },
                success: () => {
                    console.log('WebSocket连接成功');
                    this.initEventHandle();
                },
                fail: (err) => {
                    console.log('WebSocket连接失败, 错误信息:', JSON.stringify(err));
                }
            });
        } catch (error) {
            console.log('WebSocket连接异常:', error);
        }
    }

    initEventHandle() {
        try {
            this.ws.onOpen(() => {
                console.log('WebSocket连接已打开');
            });

            this.ws.onClose((res) => {
                console.log('WebSocket连接已关闭, 状态码:', res.code);
            });

            this.ws.onError((res) => {
                console.log('WebSocket错误, 详细信息:', JSON.stringify(res));
            });

            this.ws.onMessage((res) => {
                console.log('收到消息:', res.data);
                if (typeof this.onMessage === 'function') {
                    this.onMessage(res);
                }
            });
        } catch (error) {
            console.log('事件监听设置异常:', error);
        }
    }

    send(data) {
        try {
            if (this.ws && this.ws.readyState === 1) {
                this.ws.send({
                    data: data,
                    success: () => {
                        console.log('消息发送成功');
                    },
                    fail: (err) => {
                        console.log('消息发送失败:', JSON.stringify(err));
                    }
                });
            } else {
                console.log('WebSocket未连接,无法发送消息');
            }
        } catch (error) {
            console.log('发送消息异常:', error);
        }
    }

    close() {
        try {
            if (this.ws) {
                this.ws.close({
                    success: () => {
                        console.log('WebSocket关闭成功');
                    },
                    fail: (err) => {
                        console.log('WebSocket关闭失败:', JSON.stringify(err));
                    }
                });
                this.ws = null;
            }
        } catch (error) {
            console.log('关闭连接异常:', error);
        }
    }
}

let instance = null;
export default {
    getInstance() {
        if (!instance) {
            instance = new WebSocketClient();
        }
        return instance;
    }
} 

页面引用websocket.js

<script>
export default {
    data() {
        return {
            ws: null
        }
    },
    onShow() {
        this.ws = WebSocketClient.getInstance();
        this.ws.connect();
        
        // 设置消息处理函数
        this.ws.onMessage = (res) => {
            if ('判定条件') {
                // 执行你的业务逻辑
                this.handle();
            }
        };
    },
    onHide() {
        if (this.ws) {
            this.ws.close();
        }
    },
    methods: {
        handle() {
          
        }
    }
}
</script>

所遇问题

在实际使用中发现,由于是单例模式,只能最近的设备才能与服务器建立连接,之前的设备连接会被覆盖掉,如果想要多台设备均与后端建立websosocket连接,可在url处传入不同的参数。

 this.url = 'ws://yourURL' + this.generateUUID();
 // 保留现有的 generateUUID 方法作为备选
    generateUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }

这种写法虽然保证了每次页面均会与后端建立不同的连接,但是会产生一个问题:
由于generateUUID()生成的是随机数,导致每次都会建立一个新的websocket连接,这对于后端连接池非常不友好,因此建议此处使用唯一ID而不是随机数
例如我使用的是安卓设备的唯一ID,既保证了唯一性,同时相同的设备不会创建多个websocket连接

 this.url = 'ws://yourURL' + this.getDeviceId();
 // 获取设备唯一标识
    getDeviceId() {
        try {
            // 获取设备的UUID
            const uuid = plus.device.uuid;
			 console.log('UUID:', uuid);
            return uuid;
        } catch (error) {
            console.error('获取设备UUID失败:', error);s
        }
    }