当用户 A 发送消息时,客户端(如手机 APP)会在消息中明确指定接收方 ID(比如receiverId: "userB")。这个信息是客户端主动设置的,就像发邮件时必须填 “收件人邮箱” 一样。
示例消息格式:
WebSocket 网关收到消息后,会直接把完整消息(包括receiverId)转发给消息队列(或后端服务),而不关心消息该发给谁。网关的角色类似于 “快递员”—— 只负责 “收件→运输→派件”,不决定 “包裹该送到谁家”。
-
消息处理服务从队列消费消息:
消息进入队列后,专门的 “消息处理服务” 会消费这条消息,并读取其中的receiverId(如userB)。
-
查询 “用户 B 在哪个网关”:
消息处理服务通过会话管理服务(或 Redis 等存储)查询:
-
将消息路由到目标网关的队列:
消息处理服务根据查询结果,将消息转发到网关 3 专属的 RabbitMQ 队列(如gateway_3_messages)。
- 网关 3 持续监听自己的队列(
gateway_3_messages),当收到消息后,从中提取receiverId(即userB),然后:
| 组件 | 职责 |
| 客户端 |
在消息中明确指定receiverId(如userB) |
| WebSocket 网关 |
1. 接收消息并转发给队列 2. 从自己的队列取消息,推送给对应用户 |
| 消息处理服务 |
1. 解析receiverId 2. 查询用户所在网关 3. 将消息路由到目标网关队列 |
| 会话管理服务 |
存储 “用户 ID → 网关 ID” 的映射关系 |
- 用户 A:写快递时填写 “收件人:用户 B”
- WebSocket 网关:快递员,负责 “收快递→送到分拣中心” 和 “从分拣中心取件→派给用户 B”
- 消息处理服务:分拣员,根据 “收件人地址” 决定 “这个快递该发往哪个区域的站点”
- 会话管理服务:地址簿,记录 “用户 B 住在 XX 区 XX 街道”
整个过程中,“消息该发给谁” 的关键信息(receiverId)一开始就由客户端明确指定,后续各组件只需按规则处理即可。