5.1 KiB
HY Voice Room
HY Voice Room 是语音房后端 monorepo。当前架构不再自研 IM 长连接服务:房间业务状态由 room-service 承担,客户端实时消息接入腾讯云 IM,服务端只负责签发 UserSig、创建房间群组、发送房间系统消息。
Architecture
核心边界:
gateway-service是客户端 HTTP JSON 入口,负责鉴权、协议转换、签发腾讯云 IM UserSig,以及调用内部 gRPC 服务。room-service是房间业务状态 owner,负责 Room Cell、麦位、房间 presence、本地礼物榜、送礼落房间、snapshot、command log、outbox、Redis lease,以及腾讯云 IM 群组/系统消息桥接。wallet-service当前提供送礼扣费 stub,room-service的SendGift同步调用它。user-service和activity-service当前是独立进程骨架,后续分别承接用户主数据和活动消费。- 腾讯云 IM 承担客户端长连接、群消息、公屏、单聊、离线/漫游和全球接入能力;本仓库不再部署
im-service。
协议边界:
- 客户端命令面:
gateway-service暴露 HTTP JSON。 - 客户端实时面:腾讯云 IM SDK,客户端用 gateway 签发的 UserSig 登录。
- 服务内部调用:gRPC + protobuf,契约在
api/proto。 - 房间外事件:protobuf outbox,当前先落 MySQL。
Ports
本地和 Docker 编排统一使用 13xxx 端口:
| Component | Port | Purpose |
|---|---|---|
gateway-service |
13000 |
HTTP JSON |
room-service |
13001 |
gRPC |
wallet-service |
13004 |
gRPC |
user-service |
13005 |
gRPC |
activity-service |
13006 |
gRPC |
| MySQL | 13306 -> 3306 |
local Docker only |
| Redis | 13379 -> 6379 |
local Docker only |
Run Locally
Use Docker for local and test environments:
make up
Service aliases: gs/gateway, rs/room, ws/wallet, us/user, as/activity, mysql, redis.
Common commands:
make test
make build
make addr
make logs
make rebuild rs
make down
For direct host execution, each service reads its own services/<service>/configs/config.yaml.
Tencent IM
客户端获取腾讯云 IM 登录票据:
GET /api/v1/im/usersig
Authorization: Bearer <access_token>
响应 data 包含:
{
"sdk_app_id": 1400000000,
"user_id": "10001",
"user_sig": "xxx",
"expire_at_ms": 1710000000000
}
房间流程:
- 客户端先经 gateway 调
JoinRoom,让用户进入room-servicepresence。 - 客户端再用腾讯云 IM SDK 登录并加入
room_id对应的群组。 room-service在CreateRoom时通过腾讯云 IM REST API 创建同名群组。room-service在上下麦、禁言、踢人、送礼等命令提交后,通过腾讯云 IM REST API 发送房间系统自定义消息。- 公屏发言权限仍以
room-service的CheckSpeakPermission为准,线上需要接腾讯云 IM 发言前回调或等价网关校验。
腾讯云 IM 配置分别在:
services/gateway-service/configs/config.yaml
services/room-service/configs/config.yaml
services/room-service/configs/config.tencent.example.yaml
本地联调腾讯云 IM 时,gateway-service 和 room-service 必须使用同一组 sdk_app_id、secret_key,room-service 还必须配置匹配的 admin_identifier 和区域 endpoint。
基础闭环实现顺序见:
docs/voice-room-basic-loop-implementation.md
Storage Model
room-service uses MySQL as the durable source:
rooms: room metadata.room_snapshots: latest room state snapshot.room_command_log: replayable command log for recovery.room_outbox: async event records.
room-service uses Redis for current room ownership:
room:route:{room_id}
Redis lease 只保存当前执行权,不能作为恢复来源。恢复来源是 MySQL snapshot + command log。
Room Recovery
A room is not permanently bound to one process. A node is only the current executor while its Redis lease is valid.
Recovery path:
- A request reaches a node that can own the room.
- The node acquires or renews
room:route:{room_id}. - If the local Room Cell does not exist, it loads the latest MySQL snapshot.
- It replays command log records after the snapshot version.
- It installs a local Room Cell and continues processing.
This is single-active recovery, not hot standby. Short retry/reconnect windows are expected during node failure.
Project Layout
api/proto/ protobuf contracts
pkg/ shared packages, including Tencent IM signing/client
services/gateway-service/ HTTP entry service
services/room-service/ Room Cell and durable room state
services/wallet-service/ wallet stub
services/user-service/ user service
services/activity-service/ activity stub
Current Limits
- 腾讯云 IM 发言前回调尚未落 gateway handler;公屏权限不能只靠客户端自觉调用。
wallet-service和activity-service仍是基础版本。room-serviceoutbox 已持久化,但 activity/audit 消费未完整实现。- JWT、腾讯云 IM secret 等本地配置只能用开发值,线上必须走安全配置源。