⼩程序-实现实时聊天功能前端部分
⼩程序中创建webSocket连接
需求
列表页需要实时获取新消息提⽰,详情页(聊天室)实现⽤户实时聊天
页⾯逻辑
列表页
⾸先在列表页开启ws服务,并监听开启/关闭事件,ws开启后,在wx.onSocketMessage监听消息
// 列表页
onLoad(options) {
this.init();
// 监听接受消息
},
init() {
//# 开启ws
this.openWS()
},
// 开启服务
openWS() {
const token = wx.getStorageSync('token');
const app = getApp();
url: app.globalData.socketPath + '?sec-websocket-protocol=' + encodeURIComponent(token),
header: {
'content-type': 'application/json',
'from': 'wechatmini'
},
success() {},
fail() {}
})
}
复制代码
1. ws要确保只连⼀个,统⼀在列表页监听服务开启/关闭,
2. 服务断开后要重连服务,利⽤⼩程序进⼊详情后列表页不销毁特性,在列表页或详情页断线后都会执⾏列表页的重连事件
// # 1.ws要确保只连⼀个,⽤全局变量判断
!this.data.socketOpened && this.openWS();
// # 监听服务
console.log('WebSocket 已开启!')
this.data.socketOpened = true;
})
// # 重连
console.log('WebSocket 已关闭!')
this.data.socketOpened = false;
// # 在列表页⾯重连服务
this.openWS()
})
}
socket编程聊天室基本流程复制代码
重连服务
为了减轻服务器的压⼒,防⽌连不上服务会⼀直请求连接服务,做了个延时处理,⽤reconnectDelay控制,成功后再重置。断线有2种情况,⼀是连接失败,⼆是连接成功后断线:
init() {
...
console.log('WebSocket 已开启!')
this.data.socketOpened = true;
ectDelay = 0;
})
console.log('WebSocket 已关闭!')
this.data.socketOpened = false;
// 在列表页⾯重连服务,重连失败调⽤时间+1s
setTimeout(() => {
this.openWS()
ectDelay += 1000
}, ectDelay);
})
...
}
openWS() {
...
...
fail(res) {
console.log('连接失败');
// 在列表页⾯重连服务,重连失败调⽤时间+1s
setTimeout(() => {
this.openWS()
ectDelay += 1000
}, ectDelay);
}
})
},
复制代码
重连成功后,需要给服务端发送reconnect消息,根据和服务端约定,需要发送每个聊天的usif和该聊天最后⼀条消息id
...
...
// # msgList存储的是每个聊天最后⼀条消息对象
let len = this.data.msgList.length;
// # 发送重连消息
for (let i = len - 1; i >= 0; i--) {
let lastMsg = this.data.msgList[i];
// # util.sendMsg是公共⽅法,向服务端发送消息
util.sendMsg({
action: 'reconnect',
data: {
index: lastMsg.id
},
usif: lastMsg.usif
})
}
})
}
// # util.js
function sendMsg({action,data,usif}) {
data['usif'] = usif
let msg = {
action: action,
data: data
}
wx.sendSocketMessage({
data: JSON.stringify(msg),
success: function () {},
})
}
复制代码
消息处理
列表页只要标志新消息,不涉及发送,只需要对接收的消息做处理
服务端约定的message⾃定义事件返回类型说明
操作含义
fail连接成功,但是获取⽤户信息失败(⼀般在redis连接失败,或者数据被清空时出现,此时需要重连)online医⽣上线通知,此通知会⼴播所有⽤户(医⽣/普通⽤户)
push消息推送通知,收到此消息时可把数据插⼊到消息列表
pushback消息推送反馈,通知⽤户消息是否发送成功,成功则可插⼊列表,失败则需要重发
read消息已读通知,通知发消息的对象,对⽅已读此消息
reconnect断线重连时,此操作会返回对⽅最新发送的50条未读消息,可插⼊消息列表
online⽤户下线通知,此通知会⼴播所有⽤户,需要前端根据ID⾃⾏判断下线⽤户是否是在聊天的对象
// # 列表页
// # 监听接受消息
that.msgOperation({})
})
})
msgOperation({msgType,errcode = 0,data, errmsg}) {
let that = this
// # 根据不同消息类型做对应处理
switch (msgType) {
case 'push':
console.log('列表收到新消息');
// # Message是⾃定义类,⽤于对消息做初始化
data = new Message(data);
if (errcode == 0) {
/
/ # taskList是存储聊天订单
for (let i = 0; i < that.data.taskList.length; i++) {
// # 收到相应订单的新消息则对该订单进⾏hasnews标识
if (data.booking_id == that.data.taskList[i].id) {
// # 如何只改变数组中某个值的属性值,中括号法
var hasnews = 'taskList[' + i + '].hasnews'
that.setData({
[hasnews]: 1,
})
}
}
/
/ # 将新消息作为last_msg加到msgList,这⼀步是为断线重连发送消息做准备 that.data.msgList.forEach((item, idx) => {
if (item.booking_id == data.booking_id) {
item = Object.assign({}, item, data)
that.data.msgList.splice(idx, 1)
that.data.msgList.push(item)
}
})
that.setData({
msgList: that.data.msgList
})
}
break;
case 'pushback':
// # 列表页不需要对发送反馈做处理
break;
case 'read':
//消息已读反馈,根据id标记消息为已读
data = new Message(data);
var msgid = data.id;
var length = that.data.msgList.length
// # msgList更新是为了??
for (let i = length - 1; i >= 0; i--) {
if (that.data.msgList[i].id == msgid) {
let is_read = "msgList[" + i + "].is_read";
that.setData({
[is_read]: 1
})
}
}
// # 更新is_read, 消息已读/未读状态是根据taskList中的last_message来判断的 for (let i = that.data.taskList.length - 1; i >= 0; i--) {
if (that.data.taskList[i].last_message.id == msgid) {
let is_read = "taskList[" + i + "].last_message.is_read";
that.setData({
[is_read]: 1
})
}
}
break;
case 'online':
console.log('医⽣上线');
break;
case 'reconnect':
console.log('断线重连', data);
console.log('断线重连', data);
/
/ # 将收到的新消息加⼊msgList,作新消息处理
if (data.length) {
that.data.taskList.forEach((item, index) => {
for (let i = 0; i < data.length; i++) {
if (data[i].booking_id == item.id) {
var hasnews = 'taskList[' + index + '].hasnews'
that.setData({
[hasnews]: 1,
})
}
}
});
}
default:
}
},
复制代码
列表页主要负责服务开启/关闭,及对push/reconnect/read消息作处理
聊天室-详情页
服务端约定的send发送消息事件说明
操作含义
push消息推送(对⽅会在message事件中收到此消息)
read消息已读通知(对⽅会在message事件中收到此消息)
reconnect断线重连(会在⾃⼰客户端message事件中收到断线时未收到的消息)
操作:
进⼊聊天室接⼝获取历史消息列表
打开聊天室,对未读消息发送read
点击发送后,发送push
断线后重连成功,发送reconnect(列表页执⾏)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论