b站上面本期视频版本,观看视频食用更佳!点击即可跳转,找不到视频可以直接搜索我 目前叫 呆呆呆呆梦
目前已经写的文章有。并且有对应视频版本。
git项目地址 【IM即时通信系统(企聊聊)】点击可跳转
sprinboot单体项目升级成springcloud项目 【第一期】
前端项目技术选型以及页面展示【第二期】
分布式权限 shiro + jwt + redis【第三期】
给为服务添加运维模块 统一管理【第四期】
微服务数据库模块【第五期】
netty与mq在项目中的使用(第六期)】
分布式websocket即时通信(IM)系统构建指南【第七期】
上一篇中说了一下项目的构成,比较枯燥,一些基本构造方面,这一片呢,一定会更加枯燥。这一篇讲报文协议。后端嘛,不像前端花里胡哨,就是更有内涵一点。为什么这块需要着重说呢,因为聊天系统中需要设计一套保证消息可靠的机制。否则消息都不知道发过去了没有。需要通过报文去保证这些。这些都是需要去设计的。具体设计思路如下。
主要有参考这个
IM消息送达保证机制实现
这篇文章有详细明确了一下消息可靠性的保证;
这个是正常的发送逻辑。客户A发送给服务器,服务器发送给客户B。这个是之前的逻辑,就是正常的发送逻辑;msg:A用于确认客户端消息发送到服务器。但是在这种逻辑中,客户A是不清楚客户B是否收到消息的;,所以由此引入一个确认机制。
client-B向im-server发送一个ack请求包,即ack:R
im-server在成功处理后,回复client-B一个ack响应包,即ack:A
则im-server主动向client-A发送一个ack通知包,即ack:N
你会发现,一条消息的发送,分别包含(上)(下)两个半场,即msg的R/A/N三个报文,ack的R/A/N三个报文。一个应用层即时通讯消息的可靠投递,共涉及6个报文,这就是im系统中消息投递的最核心技术(如果某个im系统不包含这6个报文,不要谈什么消息的可靠性)。
理论知识讲解完毕,下面是实战演练;
如果没有收到ack消息,涉及到消息的重发。
然后中间涉及到消息的重发,在报文中需要字段来确认是否是消息的重发。直接实操一遍看一下经过的报文吧。然后看具体的报文;
0 注册消息报文
{"type":7,"params":{"openid":"56C02DF0516B4B079ABFCEC08169E577","userName":"123","loginStatus":"1"}}
1 用户A:发送消息报文
{
"type": 1,
"params": {
"msgid": "17301",
"toMessageId": "1879878-NKCNO-NKNK",
"message": "我要发消息啦",
"fileType": 0,
"isretry": false
}
}
2 用户A:客户端确认
{
"type": -1,
"params": {
"date": "Thu Jan 18 18:38:27 CST 2024",
"msgid": "17301",
"online": true,
"message": "我要发消息啦",
"isretry": "false"
},
"status": 200
}
3 用户B:收到消息
{
"activeTime": 1705574308625,
"from": "system",
"messageId": "17301",
"msg": {
"type": 2,
"params": {
"fromUser": {
"openid": "56C02DF0516B4B079ABFCEC08169E577",
"loginStatus": "1",
"userName": "123"
},
"message": "我要发消息啦",
"fileType": "0"
},
"status": 200
},
"msgType": 1,
"requestId": "08808d38-3d4c-4b80-9f9c-9c19dfe1163e",
"sessionId": "192.168.56.1:8084_1879878-NKCNO-NKNK_20240118183556",
"to": ["1879878-NKCNO-NKNK"],
"trigger": 1
}
4 用户B:发送ACK
{"type":15,"params":{"from":"client","msgid":"17301","fromUser":"56C02DF0516B4B079ABFCEC08169E577","toUser":"1879878-NKCNO-NKNK"}}
5 用户B:收到服务器确认消息
{"type":16,"params":{"date":"Thu Jan 18 18:38:28 CST 2024","message":"17301"},"status":200}
6 用户A:客户端收到ack消息 流程结束
{
"activeTime": 1705574308647,
"from": "system",
"messageId": "17301",
"msg": {
"type": 17,
"status": 200
},
"msgType": 1,
"requestId": "85a16365-6a1d-4ce1-8f99-c49a583ed1d0",
"sessionId": "192.168.56.1:8084_56C02DF0516B4B079ABFCEC08169E577_20240118183655",
"to": ["56C02DF0516B4B079ABFCEC08169E577"],
"trigger": 1
}
7 消息落库报文
{
"activeTime": 1705574309525,
"from": "system",
"messageId": "17301",
"msg": {
"type": 18,
"status": 200
},
"msgType": 1,
"requestId": "4ad1af60-56e4-4718-a668-8d94243a2173",
"sessionId": "192.168.56.1:8084_56C02DF0516B4B079ABFCEC08169E577_20240118183655",
"to": ["56C02DF0516B4B079ABFCEC08169E577"],
"trigger": 1
}
基本步骤如上.