You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Open-IM-Server/docs/rtc-signaling.md

12 KiB

OpenIM 音视频RTC信令与媒体 — 技术说明

1. 职责边界

维度 说明
OpenIM 呼叫信令编排、邀请状态Mongo、LiveKit 房间创建/删除、进房 JWT、通过消息链路把信令投递到对端在线 WebSocket + 离线推送)。
LiveKit WebRTC 媒体面(客户端持 Token 连接 externalAddress)。
协议 protocol/rtc/rtc.proto;通知类 ContentTypeprotocol/constant/rtc.go

2. 服务与配置

位置
RTC 进程入口 pkg/common/cmd/rpc_rtc.gointernal/rpc/rtc.Start
实现 internal/rpc/rtc/server.gointernal/rpc/rtc/signal.go
注册名 config.Share.RpcRegisterName.Rtc
LiveKit 配置 pkg/common/config/config.goLiveKitinternalAddressexternalAddressapiKeyapiSecrettokenExpiry

3. 接入方式(概览)

3.1 WebSocket

  1. internal/msggateway/ws_server.go:注入 RtcServiceClient
  2. internal/msggateway/client.goReqIdentifier == WSSendSignalMsg1004)。
  3. internal/msggateway/message_handler.goSendSignalMessageSignalMessageAssemble(体为 SignalMessageAssembleReq 或裸 SignalReq)。
  4. 返回:SignalResp 的 protobuf 二进制放在 Resp.Data

3.2 HTTP/rtc

路由:internal/api/router.go;封装:internal/api/rtc.goa2r.Call 将 HTTP 体映射到同名 gRPC。Prometheus 发现:GET /prometheus_discovery/rtc

详细接口与链路见第 4 节。


4. 接口清单与各接口调用链路

对外暴露形态包括:gRPC 方法名(服务 openim.rtc.RtcService)、HTTPOpenIM API 网关)、以及 WebSocket(仅映射到 SignalMessageAssemble)。以下链路按代码真实调用顺序描述。

4.1 接口总表

# gRPC 方法 HTTP 路径 WebSocket
1 SignalMessageAssemble POST /rtc/signal_message_assemble ReqIdentifier=1004WSSendSignalMsg
2 SignalGetRoomByGroupID POST /rtc/signal_get_room_by_group_id
3 SignalGetTokenByRoomID POST /rtc/signal_get_token_by_room_id
4 SignalGetRooms POST /rtc/signal_get_rooms
5 GetSignalInvitationInfo POST /rtc/get_signal_invitation_info
6 GetSignalInvitationInfoStartApp POST /rtc/get_signal_invitation_info_start_app
7 SignalSendCustomSignal POST /rtc/signal_send_custom_signal
8 GetSignalInvitationRecords POST /rtc/get_signal_invitation_records
9 DeleteSignalRecords POST /rtc/delete_signal_records

说明:SignalReq 内嵌的 getTokenByRoomID 与独立 RPC SignalGetTokenByRoomID 在服务端均落到 genToken + 返回 liveURL,前者经 SignalMessageAssemble 分发,后者经 HTTP 直达同名 gRPC。


4.2 SignalMessageAssemble

作用:处理一路信令请求,返回 SignalResp;部分分支会写 Mongo、调 LiveKit、并通过 Msg 服务发 1601 通知。

入口 A — WebSocket

  1. 客户端发送二进制帧 → internal/msggateway/client.goReqIdentifier==1004 分支。
  2. LongConnServer.SendSignalMessageGrpcHandler.SendSignalMessageinternal/msggateway/message_handler.go)。
  3. proto.UnmarshalSignalMessageAssembleReq;若失败则解 SignalReq 并填入 assembleReq.SignalReq
  4. RtcServiceClient.SignalMessageAssemble(ctx, assembleReq)gRPC 至 rtc 进程)。
  5. internal/rpc/rtc/signal.gortcServer.SignalMessageAssembleswitch req.SignalReq.PayloadhandleInvite / handleInviteInGroup / handleCancel / handleAccept / handleHungUp / handleReject / handleGetTokenByRoomID
  6. 返回 SignalMessageAssembleResp → 网关将 SignalResp proto.MarshalResp.Data 回客户端。

入口 B — HTTP

  1. POST /rtc/signal_message_assembleinternal/api/rtc.goRtcApi.SignalMessageAssemble
  2. github.com/openimsdk/tools/a2r.Call:解析 Gin 请求体 → 调用 RtcServiceClient.SignalMessageAssemble
  3. 后续与步骤 56 相同(响应经 HTTP 返回,而非 WS Resp)。

分支内典型下游(仅当对应 payload 触发时)

子逻辑 LiveKit Mongocontroller.RtcDatabasemgo/signal Msgrpcli.MsgClient.SendMsg
handleInvite CreateRoom CreateInvitation 对每个被叫 sendSignalingNotification1601
handleInviteInGroup CreateRoom CreateInvitation 同上(SessionType 为群)
handleAccept 通知主叫 1601
handleReject DeleteInvitation / RemoveInvitee 通知主叫 1601
handleCancel DeleteInvitation 通知被叫 1601
handleHungUp DeleteRoom DeleteInvitation 通知对端 1601
handleGetTokenByRoomID

若发生 SendMsg1601,后续链路见 第 7 节Kafka → msg_transfer → push → 网关 WSPushMsg 2001


4.3 SignalGetRoomByGroupID

作用:按群 ID 查当前(或最近)邀请信息,返回 InvitationInforoomID

HTTP 链路

  1. POST /rtc/signal_get_room_by_group_idRtcApi.SignalGetRoomByGroupIDa2r.Call → gRPC。
  2. internal/rpc/rtc/signal.goSignalGetRoomByGroupIDdb.GetInvitationByGroupID → Mongo signal_invitationmgo/signal.go)。
  3. modelToInvitationInfo 填响应返回。

不经过LiveKit、Msg、Kafka。


4.4 SignalGetTokenByRoomID(独立 RPC

作用:已有房间时,仅为指定用户签发 LiveKit JWT并返回 liveURLExternalAddress)。

HTTP 链路

  1. POST /rtc/signal_get_token_by_room_idRtcApi.SignalGetTokenByRoomIDa2r.Call → gRPC。
  2. internal/rpc/rtc/signal.goSignalGetTokenByRoomID(与 handleGetTokenByRoomID 同源逻辑)→ genToken(roomID, userID)
  3. 返回 SignalGetTokenByRoomIDResp

不经过Mongo不校验邀请是否存在、Msg、Kafka。


4.5 SignalGetRooms

作用:批量 roomID 查询邀请信息列表。

HTTP 链路

  1. POST /rtc/signal_get_roomsRtcApi.SignalGetRoomsa2r.Call → gRPC。
  2. SignalGetRoomsdb.GetInvitationsByRoomIDs → Mongo。
  3. 组装 []*SignalGetRoomByGroupIDResp 返回。

不经过LiveKit、Msg、Kafka。


4.6 GetSignalInvitationInfo

作用:按 roomID 查邀请详情及离线推送字段。

HTTP 链路

  1. POST /rtc/get_signal_invitation_infoRtcApi.GetSignalInvitationInfoa2r.Call → gRPC。
  2. GetSignalInvitationInfodb.GetInvitationByRoomID → Mongo。
  3. 填充 InvitationInfoOfflinePushInfo 返回。

不经过LiveKit、Msg、Kafka。


4.7 GetSignalInvitationInfoStartApp

作用:按 被叫 userID 查其相关待处理邀请(冷启动拉铃场景)。

HTTP 链路

  1. POST /rtc/get_signal_invitation_info_start_appRtcApi.GetSignalInvitationInfoStartAppa2r.Call → gRPC。
  2. GetSignalInvitationInfoStartAppdb.GetInvitationByInviteeUserID → Mongoinvitee_user_id_list 查询)。
  3. 返回邀请与 OfflinePushInfo

不经过LiveKit、Msg、Kafka。


4.8 SignalSendCustomSignal

作用:向房间内除操作者外的参与者广播 自定义信令(系统消息 1605)。

HTTP 链路

  1. POST /rtc/signal_send_custom_signalRtcApi.SignalSendCustomSignala2r.Call → gRPC。
  2. SignalSendCustomSignaldb.GetInvitationByRoomID(取邀请内 InviteeUserIDList + InviterUserID)。
  3. mcontext.GetOpUserID(ctx) 排除发送者自己。
  4. 对每个目标用户 sendCustomSignalNotificationMsgClient.SendMsgContentType=CustomSignalNotificationJSON body
  5. 若第 2 步查无邀请:打日志后返回空成功(不报错)。

若发生 SendMsg:后续同第 7 节1605 走消息总线与推送)。


4.9 GetSignalInvitationRecords

作用:分页查询通话/信令话单(signal_record)。

HTTP 链路

  1. POST /rtc/get_signal_invitation_recordsRtcApi.GetSignalInvitationRecordsa2r.Call → gRPC。
  2. GetSignalInvitationRecordsdb.SearchRecordssendID / recvID / sessionType / 时间范围 / 分页)→ Mongo signal_record
  3. 映射为 []*rtc.SignalRecord 返回。

不经过LiveKit、Msg、Kafka。


4.10 DeleteSignalRecords

作用:按话单主键 SID 列表删除记录。

HTTP 链路

  1. POST /rtc/delete_signal_recordsRtcApi.DeleteSignalRecordsa2r.Call → gRPC。
  2. DeleteSignalRecordsdb.DeleteRecords(sIDs) → Mongo。

不经过LiveKit、Msg、Kafka。


5. SignalMessageAssemble 行为摘要payload 与副作用)

(实现:internal/rpc/rtc/signal.go

动作 LiveKit Mongo 通知
Invite CreateRoom CreateInvitation 向被叫发 1601
InviteInGroup CreateRoom CreateInvitation 向被叫发 1601群 SessionType
Accept 通知主叫 1601
Reject DeleteInvitation / RemoveInvitee 通知主叫
Cancel DeleteInvitation 通知被叫
HungUp DeleteRoom DeleteInvitation 通知对端
GetTokenByRoomID嵌在 SignalReq

Tokengithub.com/livekit/protocol/authVideoGrantRoomJoin + Room + Identity),有效期由配置决定。


6. Mongo

  • 集合:signal_invitationsignal_recordpkg/common/storage/database/name.go)。
  • 模型:pkg/common/storage/model/signal.go
  • DAOpkg/common/storage/database/mgo/signal.go
  • 控制器:pkg/common/storage/controller/rtc.go

话单 SignalRecord 的写入需结合业务;GetSignalInvitationRecords 依赖该集合已有数据。


7. 信令进消息链路(SendMsg 之后)

适用于:sendSignalingNotification1601sendCustomSignalNotification1605

  1. MsgClient.SendMsginternal/rpc/msg/send.go(按 SessionType 走单聊/群聊分支)。
  2. MsgToMQ → Kafka toRedisTopickey单聊为 GenConversationUniqueKeyForSingle;群为 GroupID)。
  3. msg_transferinternal/msgtransfer/online_history_msg_handler.go)消费 → Redis seq → toMongoTopictoPushTopic
  4. pushinternal/push/push_handler.go)消费 toPushTopicPush2User / Push2Group → 网关 RPC。
  5. 网关 Client.PushMessageinternal/msggateway/client.goReqIdentifier = WSPushMsg2001Datasdkws.PushMessages 的 protobuf。

离线推送:SignalingNotification 可走离线;RoomParticipantsConnected/Disconnected1602/1603在 push 逻辑中默认不触发离线推。


8. MsgData.Options 与会话 ID缺省行为

pkg/msgprocessor/options.goOptions.Is(key)key 未设置时视为 true

RTC 侧 sendSignalingNotification 使用 make(map[string]bool) 空 mapIsHistory / IsNotNotification 等表现为 true信令在 transfer 中多走落库 + 带 seq 后推送路径。

网关下行使用 GetConversationIDByMsg:单聊信令默认挂在 si_*PushMessages.Msgs 中(IsNotification 为 false 的前缀规则)。


9. 已知风险与排查

  • 群通话信令:当前构造通知时若未设置 MsgData.GroupIDsendMsgGroupChat 的 Kafka key 与 Push2Group(ctx, groupID, ...) 可能异常;建议在发群信令时写入与 InvitationInfo.group_id 一致的 GroupID
  • 常量 16021604:协议与 push 有特殊分支,但 internal/rpc/rtc 主路径主要发 1601/1605若产品需要房间成员/流状态通知,需在扩展路径发送。

10. 常量(节选)

含义
1601 SignalingNotification
1605 CustomSignalNotification
16021604 房间参与者/流变更等push 对 1602/1603 限制离线推)

11. 端到端链路(简图)

客户端 → [WS 1004 或 HTTP /rtc] → rtc RPC → LiveKit + Mongo
                    → msg SendMsg → Kafka(toRedis) → msg_transfer → Kafka(toPush)
                    → push → msg_gateway → WS 2001 (PushMessages)
客户端 ← LiveKit(media) + OpenIM(信令推送)