全局构造websocket类,聊天室实例化应用,心跳重连,uni-app
import interfaces from "../interface/interfaces.js"import dayjs from "dayjs"export default function chatWebsocket(userId,contactId, token, that) {this.socketTask = null;this.webSocketPingTimer = null;
·
前言:我这里采用的是旧的类构造方法,大家可以查看使用新的类构造方法来写,可看阮一峰老师的ES6:https://es6.ruanyifeng.com/#docs/class
import interfaces from "../interface/interfaces.js"
import dayjs from "dayjs"
export default function chatWebsocket(userId,contactId, token, that) {
this.socketTask = null;
this.webSocketPingTimer = null;
this.webSocketReconnectCount = 0;
this.webSocketIsReconnect = true;
this.webSocketIsOpen = true;
this.userId = contactId; //接收者
this.token = token;
this.senderId = userId; //发送者
this.msg = null,
this.sendMsgStatus = false;
this.that = that;
// chatWebsocket.prototype.getMsg = function() {
// return this.msg;
// },
chatWebsocket.prototype.webSocketInit = function() {
// 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】
this.socketTask = uni.connectSocket({
url: `ws://ip地址:端口号/insoApp/websocket/talk/${this.userId}`, //es6拼接字符串、反引号
success(data) {
console.log("websocket连接成功");
},
});
// ws连接开启后登录验证
this.socketTask.onOpen((res) => {
console.log("WebSocket连接正常打开中...!");
this.webSocketPing();
// 注:只有连接正常打开中 ,才能正常收到消息
this.socketTask.onMessage((res) => {
console.log(res);
if(res) {
const result = JSON.parse(res.data);
console.log("对方发送的内容",result);
if(result.data.contactId == this.userId) {
console.log(result.data);
uni.$emit('updateMsg', result.data);
}
// uni.$emit('updateMsg', Object.assign({}, this.msg));
}
// this.that.$store.commit('setChatRecordMsg', Object.assign({}, this.msg));
});
})
// 链接开启后登录验证
this.socketTask.onError((errMsg) => {
console.log(errMsg)
console.log("ws连接异常")
this.webSocketClose();
});
// 链接开启后登录验证
this.socketTask.onClose((errMsg) => {
console.log(errMsg)
console.log("ws连接关闭")
this.webSocketClose();
});
},
// 断开连接时
chatWebsocket.prototype.webSocketClose = function(webSocketIsOpen = false) {
if(webSocketIsOpen == true) {
this.socketTask.close();
this.webSocketIsReconnect = false;
}
// 修改状态为未连接
this.webSocketIsOpen = false;
this.webSocket = null;
// 判断是否重连
if (
this.webSocketIsReconnect &&
this.webSocketReconnectCount === 0
) {
// 第一次直接尝试重连
this.webSocketReconnect();
}
},
// 定时心跳
chatWebsocket.prototype.webSocketPing = function() {
this.webSocketPingTimer = setTimeout(() => {
if (!this.webSocketIsOpen) {
return false;
}
console.log("心跳");
// const payload = {
// type: 0
// };
// this.webSocketSend("11");
clearTimeout(this.webSocketPingTimer);
// 重新执行
this.webSocketPing();
}, this.webSocketPingTime);
},
// WebSocket 重连
chatWebsocket.prototype.webSocketReconnect = function() {
return;
if (this.webSocketIsOpen) {
return false;
}
console.log("第"+this.webSocketReconnectCount+"次重连")
this.webSocketReconnectCount += 1;
// 判断是否到了最大重连次数
// if (this.webSocketReconnectCount >= 10) {
// this.webSocketWarningText = "重连次数超限";
// return false;
// }
// 初始化
console.log("开始重连")
this.webSocketInit();
// 每过 5 秒尝试一次,检查是否连接成功,直到超过最大重连次数
let timer = setTimeout(() => {
this.webSocketReconnect();
clearTimeout(timer);
}, 5000);
},
// 发送ws消息
chatWebsocket.prototype.webSocketSend = async function(sendContent, accessoryPath) {
let now = new Date();
now = dayjs(now).format('YYYY-MM-DD HH:mm:ss');
console.log("现在时间",now);
await uni.request({
url: interfaces.push,
method: "POST",
data: {
token: this.token,
userId: this.senderId, //发送者
contactId: this.userId, //接收者
sendTime: now, //发送时间
sendContent: sendContent, //发送内容
accessoryPath: accessoryPath
},
success: (res) => {
console.log(res.data);
this.msg = res.data.data;
this.that.$store.commit('setChatRecordMsg', Object.assign({}, this.msg));
}
});
}
}
总结
在开发双向聊天功能的过程中,出了很多问题,最严重的就是数据源错乱
,因为我是多个websocket一起开着的,一开始采用以下写法最后才发现是共用了同一个对象(地址指向相同),所以改用了上面的类构造写法。还有一个问题就是双向发送消息
变成了单向聊天
,经后端检测验证是url路径出了问题,只能够填写一个userId,不能同时写发送人和接收人Id,所以只需要写上我自己的id(开启自己的websocket,所有好友发送过来的消息都由这个websocket接收
),我在接收对方发送过来的消息就作了判断,当发送人id == 联系人id,我才监听反馈给聊天页面。
### 废弃代码 废弃代码 废弃代码 废弃代码 大家以史为鉴 ####
import dayjs from "dayjs"
import http from "./request.js"
import $store from "../store/index.js"
export default {
config: {
url: '',
socketTask: null,
webSocketPingTimer: null,
webSocketPingTime: 50000, // 心跳的间隔,当前为 10秒,
webSocketReconnectCount: 0,
webSocketIsReconnect: true,
webSocketIsOpen: true,
userId: null, //接收者
token: '',
senderId: null, //发送者
msg: null,
sendMsgStatus: false,
isChat: false,
},
webSocketInit(url,that) {
that.config.url = url;
// 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】
that.config.socketTask = uni.connectSocket({
url: that.config.url,
success(data) {
console.log("websocket连接成功");
},
});
// ws连接开启后登录验证
that.config.socketTask.onOpen((res) => {
console.log("WebSocket连接正常打开中...!");
// this.webSocketPing(that);
// 注:只有连接正常打开中 ,才能正常收到消息
that.config.socketTask.onMessage((res) => {
const result = Object.assign({}, JSON.parse(res.data));
console.log("聊天发送接收内容",JSON.stringify(that.config));
if(!that.config.isChat) { //消息首页
$store.commit('setChatRecordMsg', result.data);
if(result.data.unreadCount > 0) {
uni.setTabBarBadge({
index: 1,
text: result.data.unreadCount + ''
})
} else {
uni.removeTabBarBadge({
index: 1
})
}
return;
} else { //聊天页面
console.log('聊天',that.config.isChat,result.data);
//接收对方发送过来的消息 发送者id == 接收者id
if(result.data.userId == that.config.userId) {
console.log(result.data);
uni.$emit('updateMsg', result.data);
}
}
});
})
// 链接开启后登录验证
that.config.socketTask.onError((errMsg) => {
console.log(errMsg)
console.log("ws连接异常")
this.webSocketClose(that);
});
// 链接开启后登录验证
that.config.socketTask.onClose((errMsg) => {
console.log(errMsg)
console.log("ws连接关闭")
this.webSocketClose(that);
});
},
// 断开连接时
webSocketClose(that, webSocketIsReconnect = true) {
if(!webSocketIsReconnect) { //不重连
console.log('断开连接');
that.config.webSocketIsReconnect = false;
that.config.socketTask.close();
}
// 修改状态为未连接
that.config.webSocketIsOpen = false;
that.config.socketTask = null;
// 判断是否重连
if (
that.config.webSocketIsReconnect &&
that.config.webSocketReconnectCount === 0
) {
// 第一次直接尝试重连
return;
this.webSocketReconnect(that);
}
},
// 定时心跳
webSocketPing(that) {
that.config.webSocketPingTimer = setTimeout(() => {
if (!that.config.webSocketIsOpen) {
return false;
}
console.log("心跳");
// const payload = {
// type: 0
// };
// this.webSocketSend("11");
clearTimeout(that.config.webSocketPingTimer);
// 重新执行
this.webSocketPing(that);
}, this.config.webSocketPingTime);
},
// WebSocket 重连
webSocketReconnect(that) {
if (that.config.webSocketIsOpen) {
return false;
}
console.log("第"+that.webSocketReconnectCount+"次重连")
that.webSocketReconnectCount += 1;
// 判断是否到了最大重连次数
// if (this.webSocketReconnectCount >= 10) {
// this.webSocketWarningText = "重连次数超限";
// return false;
// }
// 初始化
console.log("开始重连")
this.webSocketInit(that.config.url,that);
// 每过 5 秒尝试一次,检查是否连接成功,直到超过最大重连次数
let timer = setTimeout(() => {
this.webSocketReconnect(that);
clearTimeout(timer);
}, 5000);
},
// 发送ws消息
webSocketSend(sendContent, accessoryPath, that) {
let now = new Date();
now = dayjs(now).format('YYYY-MM-DD HH:mm:ss');
return new Promise((resolve,reject)=> {
http.post('chat/talk/push',{
token: that.config.token,
userId: that.config.senderId, //发送者
contactId: that.config.userId, //接收者
sendTime: now, //发送时间
sendContent: sendContent, //发送内容
accessoryPath: accessoryPath
}).then(([err,res])=> {
if(res.data.code == 200) {
console.log('msg',res.data.data);
this.msg = res.data.data;
resolve(this.msg);
// this.that.$store.commit('setChatRecordMsg', Object.assign({}, this.msg));
} else {
uni.showToast({
title: res.data.msg, icon: 'none'
})
reject(res.data.msg)
}
}).catch(e=> {
console.warning(e);
})
})
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)