客服,即时通讯功能实现
共 3134字,需浏览 7分钟
·
2021-10-28 22:49
实现方式:
早期使用的是每个用户有聊天室和消息,监听新的聊天室的创建和新消息的创建,经过一段时间功能增加发现这种方式很费力并不好,
更好的实现是每个用户相当于有一个收件箱,只要全局监听用户的收件箱就可使轻松实现,监听聊天室和新消息创建难以实现的功能。
package:"apollo-link": "^1.2.14",
"apollo-link-http": "^1.5.17",
"aws-amplify": "^3.3.1",
"aws-amplify-react-native": "^4.2.6",
"aws-appsync": "^4.0.1",
"aws-appsync-auth-link": "^2.0.3",
"redux": "^4.0.5",
需要监听:用户的收件箱,和消息的改变(消息已读未读,撤回等)
思路:
用户的所有消息,所有聊天室放在redux中管理,
新消息弹窗提醒
当有新消息发来,新的消息带有所属聊天室的id,消息的内容,发送接收方的id,是否已读等字段。当用户的收件箱收到新消息可顶部弹窗提醒,弹窗根据聊天室的id可跳转到聊天室页面中,
每执行上述操作时,判断当前app是否处于后台,若处于后台模式则调用sdk,手机发送一条消息提醒app来新消息了。
每条消息的发送,用户点击发送消息时,可先将信息插入到redux中,同时发送请求真正发送消息,此期间可有信息发送中加载动画
接收消息
每当接收到新消息,要判断用户当前是否在聊天室内,又是否是正在聊天的聊天室发送的新消息,如果是则不用顶部弹窗提醒,将新消息插入到redux中,实现新消息的接收,若用户不在聊天室,或者不在新消息所属的聊天室则弹窗新消息提醒,
已读/未读消息
每条消息都在有hasRead字段表示这条消息对方是否已读,默认都是false,让用户进入聊天室时,获取当前聊天室的消息中是对方发送的同时hasRead为false的消息,发送请求更改这条消息的hasRead字段为true,可想将redux中的数据是想更改,同时发送请求去更改数据库中的消息信息,提升用户体验
当用户发送更改消息的请求后,对方会监听到这条消息被更改,不需要重新获取消息,只需要根据这条消息的id去更改redux中的数据即可
未读消息数量
同样放在redux中管理,进入app时,获取全部收件箱中的信息,判断hasRead为false并且发送者id是自己时数量加1,拿到当前未读消息总数,当有新的消息到来时发送dispatch将未读总数加1,当用户进入聊天室读取消息时,在上面设置已读消息时可拿到已读几条消息,已读几条全部消息数量就减几,即可实现未读消息数量,
消息列表
每条消息列表上消息这个聊天室中又几条未读消息,以及最近一条消息的内容,以及,如果你是店家,显示买家的头像和昵称,如果你是买家显示商店的logo和名称,需要做个判断(聊天室数据中有聊天室中商店的信息和两方的id),商家端判断聊天室中的商店的所有者是不是自己,需要拿到聊天室的userIds即用户id组成的数组中和自己id不同的即是买家id,获取买家的公开信息,以显示
消息列表中每条聊天室展示获取未读消息:去redux中根据聊天室id获取这个聊天室中的信息中发送者id和自己id不同并且hasRead为false的消息数量
最新消息:同样通过聊天室id拿到消息,拿最后一项显示
以上实现就需要redux中的数据保存形式是一个对象,键是聊天室的id,值是聊天室中的消息数组
实现监听代码示例:
消息创建的订阅
export const createdMessageInbox = /* GraphQL */ `
subscription CreatedMessageInbox($receiverId: ID!) {
createdMessageInbox(receiverId: $receiverId) {
id
content
senderId
receiverId
conversationId
sentTime
hasRead
}
}
`;
let subCreatedMessage: any = null; // 外面定义监听以实现取消订阅
const subscribeCreatedMessageInbox = () => {
subCreatedMessage?.unsubscribe(); // Subscription before unsubscribe
subCreatedMessage = API.graphql(
graphqlOperation(createdMessageInbox, { receiverId: username })
).subscribe({
next: (event: any) => {
if (event?.value?.data) { // 如果正常有数据的话
const message = event.value.data.createdMessageInbox; // 新消息
const conversationId = message.conversationId; // 新消息所属聊天室的id
// Send a system notification when the application is in the background
if (AppState.currentState !== "active") {
sendPushNotification({
title: "new message",
body: message.content,
});
}
// Add to Redux to save
receiverMessageInbox({ // redux将新消息放到消息数组中
message,
conversationId,
})(dispatch);
// New news pop-up
haveNewMessage()(dispatch);// 新消息弹窗信息组件获取当前状态,判断是否需要弹出
popupParams({ // 新消息弹窗所需的信息
message: message.content,
conversationId,
receiverId: message.senderId, // Senderid is username not receiverId
})(dispatch);
unreadMessageInboxNumber(1)(dispatch); // add 1 unread messageInbox quantity
}
},
error: (err: any) => {
error("createdMessage error", err);
},
});
};
具体代码为详细展示,以上仅是实现思路。
最后如果对你有帮助,或疑问欢迎点赞评论,一键三连~