feat(phase2e-2): WebSocket 信令协议 13 事件全量落地(Task 6)
将 meeting.* 事件族从 Task 5 的 PublishToUser 循环升级为完整 WS 信令协议:
抽离统一广播层、扩容 MediaOrchestrator 接口、实现 8 个 C→S 事件业务逻辑
+ Redis 资源追踪 + host 权限校验,端到端 18/18 PASS。
核心产出:
- 新建 MeetingBroadcaster(统一广播层,REST/WS 共用)
- 新建 MeetingSignalService 8 C→S 事件 + cleanupUserResources
- 新建 MeetingWSHandler 薄层 controller
- MediaOrchestrator 扩容 9 方法 + NoopMediaOrchestrator 占位(Task 7 替换)
- C→S 白名单机制防恶意伪造广播事件
- Redis Set 资源追踪防 mediasoup 端资源泄漏
文档同步:
- docs/api/frontend/meeting.md 追加 §WebSocket 信令协议(Task 6)200 行
- docs/progress/CURRENT_STATUS.md + project-context.mdc + 实施计划 Task 6 ✅
Made-with: Cursor
This commit is contained in:
@@ -92,23 +92,43 @@ const (
|
||||
MeetingChatRetentionHours = 24 // 会议聊天保留时长(会议结束后)
|
||||
)
|
||||
|
||||
// 会议 WS 事件常量(设计文档 §6.3,11 个事件)
|
||||
// 会议 WS 事件常量(设计文档 §6.3)
|
||||
// 命名格式:meeting.{domain}.{action}
|
||||
// 方向说明:C→S(客户端发往服务端,需 ACK);S→C(服务端广播/定向推送,不需 ACK)
|
||||
const (
|
||||
// 房间级事件
|
||||
MeetingWSEventRoomEnded = "meeting.room.ended" // 会议已结束
|
||||
MeetingWSEventRoomLocked = "meeting.room.locked" // 会议被锁定(等候室,Phase 2e-3)
|
||||
MeetingWSEventRoomHostChange = "meeting.room.host.changed" // 主持人变更
|
||||
// ====== 房间组(3 个)======
|
||||
MeetingWSEventRoomJoin = "meeting.room.join" // C→S:加入会议后的"宣告在线",绑定 WS 连接 ↔ roomCode
|
||||
MeetingWSEventRoomLeave = "meeting.room.leave" // C→S:主动离会(等价 REST leave,但保留信令触发入口)
|
||||
MeetingWSEventRoomEnded = "meeting.room.ended" // S→C:会议已结束(广播全员)
|
||||
|
||||
// 成员级事件
|
||||
MeetingWSEventMemberJoined = "meeting.member.joined" // 新成员加入
|
||||
MeetingWSEventMemberLeft = "meeting.member.left" // 成员离开
|
||||
MeetingWSEventMemberStateChange = "meeting.member.state.changed" // 麦克风 / 摄像头状态变化
|
||||
MeetingWSEventMemberKicked = "meeting.member.kicked" // 被移出
|
||||
// ====== 成员组(5 个)======
|
||||
MeetingWSEventMemberJoined = "meeting.member.joined" // S→C:新成员加入
|
||||
MeetingWSEventMemberLeft = "meeting.member.left" // S→C:成员离开
|
||||
MeetingWSEventMemberStateChange = "meeting.member.state.changed" // 双向:麦克风 / 摄像头状态变化(host 可带 target_user_id 强制静音他人)
|
||||
MeetingWSEventMemberKicked = "meeting.member.kicked" // S→C:被移出会议(定向发给被踢者)
|
||||
MeetingWSEventMemberProducerNew = "meeting.member.producer.new" // S→C:有新 producer 可订阅(produce.start 成功后广播)
|
||||
MeetingWSEventHostChanged = "meeting.host.changed" // S→C:主持人变更
|
||||
|
||||
// 媒体级事件(Go 发起,驱动客户端 mediasoup-client 订阅/取消)
|
||||
MeetingWSEventProducerNew = "meeting.producer.new" // 有新 producer 可订阅
|
||||
MeetingWSEventProducerClosed = "meeting.producer.closed" // producer 已关闭
|
||||
MeetingWSEventConsumerResumed = "meeting.consumer.resumed" // consumer 已恢复(由服务端触发)
|
||||
MeetingWSEventChatMessage = "meeting.chat.message" // 会议内文字聊天
|
||||
// ====== 媒体组(5 个,mediasoup signaling 桥接)======
|
||||
MeetingWSEventTransportCreate = "meeting.transport.create" // C→S→Node:创建 Transport
|
||||
MeetingWSEventTransportConnect = "meeting.transport.connect" // C→S→Node:Transport DTLS 握手
|
||||
MeetingWSEventProduceStart = "meeting.produce.start" // C→S→Node:创建 Producer(广播 producer.new)
|
||||
MeetingWSEventConsumeStart = "meeting.consume.start" // C→S→Node:订阅远端 Producer,创建本地 Consumer
|
||||
MeetingWSEventProducerClose = "meeting.producer.close" // C→S→Node:关闭自己的 Producer(推流停止)
|
||||
|
||||
// ====== 补充事件(非 §6.3 核心 11 事件,但业务必须)======
|
||||
MeetingWSEventChatMessage = "meeting.chat.message" // S→C:会议内文字聊天广播(REST SendChat 触发)
|
||||
)
|
||||
|
||||
// MeetingWSClientEvents 客户端可主动发起的 WS 事件(C→S)白名单
|
||||
// 用于 WS 消息路由时快速校验事件名合法性
|
||||
var MeetingWSClientEvents = []string{
|
||||
MeetingWSEventRoomJoin,
|
||||
MeetingWSEventRoomLeave,
|
||||
MeetingWSEventMemberStateChange,
|
||||
MeetingWSEventTransportCreate,
|
||||
MeetingWSEventTransportConnect,
|
||||
MeetingWSEventProduceStart,
|
||||
MeetingWSEventConsumeStart,
|
||||
MeetingWSEventProducerClose,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user