285 lines
5.4 KiB
Markdown
285 lines
5.4 KiB
Markdown
# 📘 WebSocket 通讯协议设计文档
|
||
|
||
## 1. 概述
|
||
|
||
本协议用于实现 **即时聊天(IM)系统的实时消息传输**。
|
||
客户端通过 WebSocket 连接后与服务器保持长连接,实现消息推送、状态同步、群聊与单聊。
|
||
|
||
**支持功能**:
|
||
|
||
- 用户登录鉴权
|
||
- 单聊消息发送/接收
|
||
- 群聊消息发送/接收
|
||
- 消息撤回、已读回执
|
||
- 心跳保活与断线重连
|
||
- 系统通知(好友请求、群邀请)
|
||
|
||
------
|
||
|
||
## 2. 消息传输格式
|
||
|
||
### 2.1 基础消息结构(JSON)
|
||
|
||
```
|
||
{
|
||
"type": "MESSAGE_TYPE",
|
||
"requestId": "string", // 客户端生成的请求ID,便于幂等
|
||
"from": 1001, // 发送者ID
|
||
"to": 1002, // 接收者ID(单聊)或群ID(群聊)
|
||
"chatType": "single", // "single" | "group"
|
||
"contentType": "text", // "text" | "image" | "file" | "voice" | "system"
|
||
"content": "消息内容或文件URL",
|
||
"timestamp": 1700000000 // Unix时间戳
|
||
}
|
||
```
|
||
|
||
------
|
||
|
||
### 2.2 常用 type 枚举
|
||
|
||
| type | 说明 |
|
||
| -------------- | ------------------------- |
|
||
| AUTH | 握手鉴权 |
|
||
| HEARTBEAT | 心跳保活 |
|
||
| MESSAGE | 普通聊天消息(单聊/群聊) |
|
||
| MESSAGE_ACK | 消息已读/送达回执 |
|
||
| MESSAGE_RECALL | 消息撤回 |
|
||
| FRIEND_REQUEST | 好友申请通知 |
|
||
| GROUP_INVITE | 群邀请通知 |
|
||
| SYSTEM_NOTICE | 系统公告/通知 |
|
||
| ERROR | 错误消息 |
|
||
|
||
------
|
||
|
||
## 3. 握手与鉴权
|
||
|
||
### 3.1 客户端连接
|
||
|
||
```
|
||
ws://example.com/ws?token=xxxx
|
||
```
|
||
|
||
- 客户端通过 Token 鉴权
|
||
- 服务器验证 Token 后,返回 AUTH_SUCCESS 或 AUTH_FAIL
|
||
|
||
### 3.2 服务端响应示例
|
||
|
||
**成功:**
|
||
|
||
```
|
||
{
|
||
"type": "AUTH",
|
||
"status": "success",
|
||
"userId": 1001,
|
||
"timestamp": 1700000000
|
||
}
|
||
```
|
||
|
||
**失败:**
|
||
|
||
```
|
||
{
|
||
"type": "AUTH",
|
||
"status": "fail",
|
||
"code": 1006,
|
||
"message": "Token无效或过期"
|
||
}
|
||
```
|
||
|
||
------
|
||
|
||
## 4. 心跳机制
|
||
|
||
### 4.1 客户端发送
|
||
|
||
```
|
||
{
|
||
"type": "HEARTBEAT",
|
||
"timestamp": 1700000000
|
||
}
|
||
```
|
||
|
||
### 4.2 服务器响应
|
||
|
||
```
|
||
{
|
||
"type": "HEARTBEAT",
|
||
"timestamp": 1700000000
|
||
}
|
||
```
|
||
|
||
- **客户端**:每隔 30 秒发送一次心跳
|
||
- **服务器**:若 2 倍心跳时间未收到消息,则断开连接
|
||
|
||
------
|
||
|
||
## 5. 消息传输
|
||
|
||
### 5.1 单聊消息
|
||
|
||
客户端发送:
|
||
|
||
```
|
||
{
|
||
"type": "MESSAGE",
|
||
"requestId": "uuid-001",
|
||
"from": 1001,
|
||
"to": 1002,
|
||
"chatType": "single",
|
||
"contentType": "text",
|
||
"content": "你好",
|
||
"timestamp": 1700000000
|
||
}
|
||
```
|
||
|
||
服务器推送给接收者:
|
||
|
||
```
|
||
{
|
||
"type": "MESSAGE",
|
||
"messageId": 50001,
|
||
"from": 1001,
|
||
"to": 1002,
|
||
"chatType": "single",
|
||
"contentType": "text",
|
||
"content": "你好",
|
||
"timestamp": 1700000000
|
||
}
|
||
```
|
||
|
||
------
|
||
|
||
### 5.2 群聊消息
|
||
|
||
```
|
||
{
|
||
"type": "MESSAGE",
|
||
"requestId": "uuid-002",
|
||
"from": 1001,
|
||
"to": 3001, // 群ID
|
||
"chatType": "group",
|
||
"contentType": "image",
|
||
"content": "http://img.example.com/xxx.jpg",
|
||
"timestamp": 1700000000
|
||
}
|
||
```
|
||
|
||
服务器会 **推送到群成员列表(除了自己)**。
|
||
|
||
------
|
||
|
||
### 5.3 消息回执(MESSAGE_ACK)
|
||
|
||
客户端收到消息后发送:
|
||
|
||
```
|
||
{
|
||
"type": "MESSAGE_ACK",
|
||
"messageId": 50001,
|
||
"from": 1002,
|
||
"to": 1001,
|
||
"chatType": "single",
|
||
"status": "read",
|
||
"timestamp": 1700000000
|
||
}
|
||
```
|
||
|
||
服务器更新消息状态,并可推送给发送方。
|
||
|
||
------
|
||
|
||
### 5.4 消息撤回(MESSAGE_RECALL)
|
||
|
||
客户端请求撤回消息:
|
||
|
||
```
|
||
{
|
||
"type": "MESSAGE_RECALL",
|
||
"messageId": 50001,
|
||
"from": 1001,
|
||
"to": 1002,
|
||
"chatType": "single",
|
||
"timestamp": 1700000010
|
||
}
|
||
```
|
||
|
||
服务器验证是否允许撤回(时间限制、权限等),允许则推送给接收方:
|
||
|
||
```
|
||
{
|
||
"type": "MESSAGE_RECALL",
|
||
"messageId": 50001,
|
||
"from": 1001,
|
||
"chatType": "single",
|
||
"status": "success",
|
||
"timestamp": 1700000010
|
||
}
|
||
```
|
||
|
||
------
|
||
|
||
## 6. 好友 / 群邀请通知
|
||
|
||
### 6.1 好友申请(FRIEND_REQUEST)
|
||
|
||
```
|
||
{
|
||
"type": "FRIEND_REQUEST",
|
||
"requestId": "uuid-003",
|
||
"from": 1001,
|
||
"to": 1002,
|
||
"content": "加个好友吧",
|
||
"timestamp": 1700000020
|
||
}
|
||
```
|
||
|
||
### 6.2 群邀请(GROUP_INVITE)
|
||
|
||
```
|
||
{
|
||
"type": "GROUP_INVITE",
|
||
"inviteId": "uuid-004",
|
||
"groupId": 3001,
|
||
"inviter": 1001,
|
||
"invitee": 1003,
|
||
"content": "邀请你加入群聊",
|
||
"timestamp": 1700000030
|
||
}
|
||
```
|
||
|
||
------
|
||
|
||
## 7. 错误处理(ERROR)
|
||
|
||
```
|
||
{
|
||
"type": "ERROR",
|
||
"code": 2300,
|
||
"message": "消息发送失败",
|
||
"requestId": "uuid-001",
|
||
"timestamp": 1700000040
|
||
}
|
||
```
|
||
|
||
- **code** 对应响应 Code 规范
|
||
- **requestId** 可帮助客户端确认失败的具体请求
|
||
|
||
------
|
||
|
||
## 8. 断线重连
|
||
|
||
- 客户端断线后,尝试每隔 5 秒重连一次
|
||
- 重连成功后,重新发送 AUTH 消息进行鉴权
|
||
- 重连后可请求 **未读消息同步**(message 表或 Redis 缓存)
|
||
|
||
------
|
||
|
||
## 9. 附录:contentType 示例
|
||
|
||
| contentType | content 示例 | 描述 |
|
||
| ----------- | ---------------------------------- | ----------------- |
|
||
| text | "你好" | 文本消息 |
|
||
| image | "http://img.example.com/xxx.jpg" | 图片 URL |
|
||
| file | "http://file.example.com/xxx.pdf" | 文件 URL + 文件名 |
|
||
| voice | "http://audio.example.com/xxx.mp3" | 语音 URL + 时长 |
|
||
| system | "用户xxx加入群" | 系统消息 | |