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.
 
 
 
 
 
 

181 lines
4.5 KiB

import store from '@/uni_modules/vrapile-im/store'
/**
* @param {*} url wss or ws
* @param {*} paramStr 加在ws url后面的请求参数,形如:name=张三&id=12
* @param {*} heartbeatTimeout 心跳时间 单位:毫秒
* @param {*} reconnInterval 重连间隔时间 单位:毫秒
*/
export class TioSocket {
constructor(url, paramStr, heartbeatTimeout, reconnInterval) {
this.firstUrl = url;
this.reconnUrl = url;
if (paramStr) {
this.firstUrl += '?' + paramStr;
this.reconnUrl += '?' + paramStr + "&reconnect=true";
} else {
this.reconnUrl += "?reconnect=true";
}
this.closeByUser = false;
this.lockReconnect = false;
this.reconnectCount = 0;
// 最后连接时间
this.lastConnectTime = new Date().getTime();
// 重连时间
this.reconnInterval = reconnInterval;
// 心跳时间
this.heartbeatTimeout = heartbeatTimeout;
this.ws = null;
this.connect = function(isReconnect) {
// 这里连接的时候,先关闭,避免出现多个连接
uni.closeSocket({
success:() => {
this.ws = uni.connectSocket({
url: this.firstUrl,
success(res) {
console.log("WebSocket成功关闭,连接成功")
},
fail(err) {
console.log("WebSocket成功关闭,连接失败:" + err)
}
});
},
fail:() => {
this.ws = uni.connectSocket({
url: this.firstUrl,
success(res) {
console.log("WebSocket关闭失败,连接成功")
},
fail(err) {
console.log("WebSocket关闭失败,连接失败:" + err)
}
});
}
})
this.ws.onOpen((e) => {
if(!isReconnect){
uni.sendSocketMessage({
data: JSON.stringify({code:1})
})
store.commit('CLEAN_MESSAGE', {})
}
this.reset();
})
store.commit('SET_SOCKET', this)
this.ws.onMessage((e) => {
let data = JSON.parse(e.data);
if(data.code == 2){
store.commit('ADD_MESSAGE', data.message)
}
this.reset();
})
this.ws.onClose((e) => {
console.error("WebSocket关闭了:" + JSON.stringify(e))
this.clearAllTimeoutTask();
})
this.ws.onError((e) => {
console.error("WebSocket错误了:" + JSON.stringify(e))
this.clearAllTimeoutTask();
if(!this.closeByUser){
this.reconn();
}
})
return this.ws
}
this.reconn = () => {
// 重连次数,防止疯狂重连导致系统挂掉
if(this.reconnectCount++ > 10){ return;}
// 防止多个方法调用,多处重连
if (this.lockReconnect) { return;}
this.lockReconnect = true;
this.reconnIntervalTask = setTimeout(() => {
this.ws = this.connect(true)
this.lockReconnect = false;
}, this.reconnInterval)
}
this.ping = () => {
uni.sendSocketMessage({
data: JSON.stringify({code:0})
})
};
this.send = (data) => {
uni.sendSocketMessage({
data: data
})
};
this.close = (bool) => {
this.lockReconnect = false;
this.closeByUser = bool;
uni.closeSocket({
success:() => {
console.info("WebSocket关闭成功")
}
})
};
this.reset = () => {
this.clearAllTimeoutTask();
// 重置重连次数
this.reconnectCount = 0;
// 重置最后连接时间
this.lastConnectTime = new Date().getTime();
// 启动心跳任务
this.pingIntervalTask = setTimeout(() => {
this.ping();
}, this.heartbeatTimeout);
}
this.clearAllTimeoutTask = () => {
// 清除重连任务
if (this.reconnIntervalTask) {
clearTimeout(this.reconnIntervalTask);
}
// 清除心跳任务
if(this.pingIntervalTask){
clearTimeout(this.pingIntervalTask)
}
}
this.getReadyState = () => {
// CONNECTING:值为0,表示正在连接。
// OPEN:值为1,表示连接成功,可以通信了。
// CLOSING:值为2,表示连接正在关闭。
// CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
return this.ws.readyState;
}
}
}
/**
* 获取聊天唯一Key
* type 0-私聊,1-群里
* chatId 聊天对象,好友ID或群聊ID
* fromId 发消息人ID
*
*/
export function getChatKey(type, chatId, fromId) {
// 私聊
if(type == 0){
if(chatId*1 < fromId*1){
return "im:message:friend-" + chatId + "-" + fromId
}else{
return "im:message:friend-" + fromId + "-" + chatId
}
}else{
return "im:message:group-" + chatId
}
}