分布式websocket即时通信(IM)系统保证消息可靠性【第八期】

b站上面本期视频版本,观看视频食用更佳!点击即可跳转,找不到视频可以直接搜索我 目前叫 呆呆呆呆梦

目前已经写的文章有。并且有对应视频版本。
git项目地址 【IM即时通信系统(企聊聊)】点击可跳转
sprinboot单体项目升级成springcloud项目 【第一期】
前端项目技术选型以及页面展示【第二期】
分布式权限 shiro + jwt + redis【第三期】
给为服务添加运维模块 统一管理【第四期】
微服务数据库模块【第五期】
netty与mq在项目中的使用(第六期)】
分布式websocket即时通信(IM)系统构建指南【第七期】

前言

上一篇中说了一下项目的构成,比较枯燥,一些基本构造方面,这一片呢,一定会更加枯燥。这一篇讲报文协议。后端嘛,不像前端花里胡哨,就是更有内涵一点。为什么这块需要着重说呢,因为聊天系统中需要设计一套保证消息可靠的机制。否则消息都不知道发过去了没有。需要通过报文去保证这些。这些都是需要去设计的。具体设计思路如下。

1.如何保证两个用户之间消息可靠

主要有参考这个
IM消息送达保证机制实现
这篇文章有详细明确了一下消息可靠性的保证;

1.1 正常逻辑

分布式websocket即时通信(IM)系统保证消息可靠性【第八期】_第1张图片
这个是正常的发送逻辑。客户A发送给服务器,服务器发送给客户B。这个是之前的逻辑,就是正常的发送逻辑;msg:A用于确认客户端消息发送到服务器。但是在这种逻辑中,客户A是不清楚客户B是否收到消息的;,所以由此引入一个确认机制。

1.2带有确认机制

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个报文,不要谈什么消息的可靠性)。

理论知识讲解完毕,下面是实战演练;

2.具体实践

分布式websocket即时通信(IM)系统保证消息可靠性【第八期】_第2张图片

如果没有收到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
}

基本步骤如上.

你可能感兴趣的:(分布式,websocket,网络协议)