erDiagram USER ||--o{ FRIEND : "1:n" USER ||--o{ FRIEND_APPLY : "1:n" USER_ID ||--|| USER : "1:1" USER { INT uid PK VARCHAR(255) name VARCHAR(255) email VARCHAR(255) pwd VARCHAR(255) nick VARCHAR(255) desc INT sex VARCHAR(255) icon } FRIEND { INT id PK INT self_id INT friend_id VARCHAR(255) back } FRIEND_APPLY { BIGINT id PK INT from_uid INT to_uid SMALLINT status } USER_ID { INT id PK }
flowchart TD A[用户A发起申请] --> B{系统验证} B -->|验证通过| C[写入friend_apply表] C --> D[通知用户B] D --> E{用户B操作} E -->|同意| F[更新申请状态为1] F --> G{建立双向好友} G --> H[插入用户A的好友记录] H --> I[插入用户B的好友记录] I --> J[返回成功提示] E -->|拒绝| K[更新状态为2] K --> L[返回拒绝通知] E -->|超时未处理| M[更新状态为3] M --> N[清理过期申请] style A fill:#b3e2cd,stroke:#333 style B fill:#fdcdac,stroke:#333 style C fill:#cbd5e8,stroke:#333 style D fill:#cbd5e8,stroke:#333 style E fill:#fdcdac,stroke:#333 style F fill:#cbd5e8,stroke:#333 style G fill:#fdcdac,stroke:#333 style H fill:#cbd5e8,stroke:#333 style I fill:#cbd5e8,stroke:#333 style J fill:#b3e2cd,stroke:#333 style K fill:#f4cae4,stroke:#333 style L fill:#f4cae4,stroke:#333 style M fill:#e6f5c9,stroke:#333 style N fill:#e6f5c9,stroke:#333
graph LR A[用户A申请] --> B{用户B处理} B -->|同意| C[status=1] B -->|拒绝| D[status=2] B -->|超时| E[status=3] C --> F[插入双向好友记录] F --> G["INSERT INTO friend VALUES(81,1002,1019,'zack')"] F --> H["INSERT INTO friend VALUES(82,1019,1002,'')"]
| 字段名 | 类型 | 约束 | 描述 | |------------|--------------|-------------------------|---------------------------| | id | BIGINT | PK, AUTO_INCREMENT | 自增主键 | | from_uid | INT | NOT NULL | 申请人ID(关联user.uid) | | to_uid | INT | NOT NULL | 被申请人ID(关联user.uid) | | status | SMALLINT | DEFAULT 0 | 状态(0-待处理,1-已同意) | 唯一约束: - 联合唯一索引from_to_uid:防止重复申请
4. 用户ID生成表(user_id)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
sequenceDiagram participant Client participant DB Client->>DB: 调用reg_user存储过程 Note right of DB: 开始事务 DB->>DB: 检查用户名/邮箱唯一性 alt 存在重复 DB-->>Client: 返回0 else 可注册 DB->>user_id: UPDATE id=id+1 DB->>user_id: SELECT id DB->>user: 插入新用户记录 DB-->>Client: 返回新uid end Note right of DB: 提交事务
1 2 3 4 5 6 7 8 9
| 字段名 | 类型 | 约束 | 描述 | |------------|--------------|------------|---------------------------| | id | INT | PK | 当前可分配的最大用户ID |
工作机制: 通过存储过程reg_user实现ID自增: ```sql UPDATE user_id SET id = id + 1; -- 原子性递增 SELECT id INTO @new_id FROM user_id;
sequenceDiagram participant ClientA as 客户端A participant ClientB as 客户端B participant Gateway as 网关服务 participant MySQL as 数据库 participant PushService as 推送服务
Note over ClientA: 发起好友申请(HTTP) ClientA->>Gateway: POST /friends/apply {to_uid:10002} Gateway->>MySQL: 查询users表 WHERE uid=10002 alt 目标用户存在 MySQL-->>Gateway: 返回用户记录 Gateway->>MySQL: INSERT INTO friend_applies (from_uid,to_uid,status) MySQL-->>Gateway: 插入成功 Gateway->>PushService: 触发推送标记 Gateway-->>ClientA: 200 OK else 用户不存在 MySQL-->>Gateway: 无记录 Gateway-->>ClientA: 404错误 end
Note over ClientB: 定期轮询申请(HTTP) loop 每5秒轮询 ClientB->>Gateway: GET /friends/pending Gateway->>MySQL: SELECT * FROM friend_applies WHERE to_uid=10002 MySQL-->>Gateway: 返回申请列表 alt 存在新申请 Gateway-->>ClientB: 返回申请数据 else 无新申请 Gateway-->>ClientB: 204 No Content end end
Note over ClientB: 响应申请(HTTP) ClientB->>Gateway: PUT /friends/response {apply_id:123,status:1} Gateway->>MySQL: UPDATE friend_applies SET status=1 Gateway->>MySQL: BEGIN TRANSACTION Gateway->>MySQL: INSERT INTO friends (self_id,friend_id) VALUES (10001,10002) Gateway->>MySQL: INSERT INTO friends (self_id,friend_id) VALUES (10002,10001) Gateway->>MySQL: COMMIT Gateway-->>ClientB: 200 OK
sequenceDiagram participant Sender as 发送方 participant Receiver as 接收方 participant Gateway as 网关服务 participant MsgServer as 消息服务 participant MySQL as 数据库 participant Redis as 缓存服务
Note over Sender: 发送消息(HTTP) Sender->>Gateway: POST /messages {to_uid:10002, content} Gateway->>MySQL: 验证to_uid存在性 alt 接收方存在 Gateway->>MsgServer: 转发消息 MsgServer->>MySQL: INSERT INTO messages (...) MsgServer->>Redis: 存储离线消息 MsgServer-->>Gateway: 200 OK Gateway-->>Sender: 发送成功 else 接收方不存在 Gateway-->>Sender: 404错误 end
Note over Receiver: 消息拉取(HTTP) loop 每3秒轮询 Receiver->>Gateway: GET /messages/pending Gateway->>Redis: 检查离线消息 alt 存在新消息 Redis-->>Gateway: 返回消息列表 Gateway-->>Receiver: 200 OK + 消息数据 else 无新消息 Gateway-->>Receiver: 204 No Content end end
Note over Sender,Receiver: 文件传输(TCP直连) Sender->>Receiver: TCP连接建立(IP:PORT) Sender->>Receiver: 发送文件流数据 Receiver-->>Sender: ACK确认包
%% 消息传递流程 flowchart TD A[用户输入消息] --> B{消息类型} B --> |文本| C[生成唯一UUID] C --> D{文本长度 > 1024?} D --> |是| E[立即发送分片数据] D --> |否| F[缓存消息] E --> G[清空缓存] F --> H[点击发送按钮] H --> I[TCP发送请求] I --> J{服务器处理} subgraph 服务器路由 J --> K[解析 fromuid/touid] K --> L{用户在线?} L --> |本服务器在线| M[直接推送通知] L --> |跨服务器/离线| N[gRPC转发] N --> O[目标服务器接收] O --> P{用户在线?} P --> |是| Q[推送至客户端] P --> |否| R[存入离线消息] end Q --> S[接收方UI更新] M --> S S --> T[显示新消息] J --> U[返回响应ID_TEXT_CHAT_MSG_RSP] U --> V[客户端更新状态]
%% 好友查询与申请流程 flowchart TD subgraph 客户端交互 A[用户输入UID/昵称] --> B[显示加载动画] B --> C{发送搜索请求\nID_SEARCH_USER_REQ} C --> |成功| D[展示FindSuccessDlg] C --> |失败| E[展示FindFailDlg] D --> F[点击添加按钮] F --> G[弹出ApplyFriend对话框] G --> H{发送申请请求\nID_ADD_FRIEND_REQ} end
subgraph 服务器处理 I[接收ID_SEARCH_USER_REQ] --> J{查询Redis/DB} J --> |存在| K[返回用户信息] J --> |不存在| L[返回错误码] M[接收ID_ADD_FRIEND_REQ] --> N[更新MySQL申请记录] N --> O[查询touid所在服务器] O --> P{是否本服务器?} P --> |是| Q[直接推送通知] P --> |否| R[gRPC转发请求] end
subgraph 跨服务器通信 R --> S[目标服务器接收请求] S --> T{用户在线?} T --> |在线| U[通过Session推送] T --> |离线| V[记录离线消息] end
subgraph 数据库操作 N -.-> W[INSERT friend_apply] J -.-> X[SELECT user表] W -.-> Y[ON DUPLICATE更新] end
%% 登录功能流程图 sequenceDiagram participant Client as 客户端 participant GateServer as 网关服务 participant MySQL as 用户数据库 participant StatusServer as 状态服务 participant ChatServer as 聊天服务
Client->>Client: 用户输入用户名/密码 Client->>Client: 点击login_btn按钮 alt 输入校验失败 Client->>Client: 显示错误提示 else 校验通过 Client->>GateServer: POST /user_login (加密密码) GateServer->>MySQL: 查询用户密码 alt 用户不存在/密码错误 GateServer->>Client: 返回错误码PasswdInvalid else 验证通过 GateServer->>StatusServer: gRPC GetChatServer(uid) StatusServer->>StatusServer: 轮询选择可用聊天服务器 StatusServer->>GateServer: 返回host+token GateServer->>Client: 返回登录成功及服务器信息 Client->>ChatServer: 使用token建立长连接 end end
%% 验证码发送流程图 sequenceDiagram participant Client as 客户端 participant GateServer as 网关服务 participant VarifyServer as 验证服务 participant Redis as Redis缓存 participant Email as 邮箱服务
Client->>GateServer: POST /get_verify_code (邮箱) GateServer->>VarifyServer: gRPC GetVarifyCode(邮箱) alt 首次请求 VarifyServer->>VarifyServer: 生成4位随机验证码 VarifyServer->>Redis: SET code_邮箱=验证码(1分钟过期) VarifyServer->>Email: 调用nodemailer发送邮件 Email-->>VarifyServer: 发送结果 else 重复请求(1分钟内) VarifyServer->>Redis: GET code_邮箱 Redis-->>VarifyServer: 返回已有验证码 end VarifyServer-->>GateServer: 返回操作结果 GateServer-->>Client: 返回成功/错误信息
%% 文件传输流程图 sequenceDiagram participant Client as 客户端 participant TcpClient as TCP连接模块 participant LogicSystem as 逻辑处理系统 participant FileSystem as 文件存储系统 participant FileWorker as 文件写入线程