前言
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
}
}