# 视频通话建立流程 Tinode 通过 [WebRTC](https://webrtc.org/) 支持点对点视频通话。下图展示了两个用户 `Alice` 和 `Bob` 之间的通话建立流程。该流程概念上类似于 [SIP](https://en.wikipedia.org/wiki/Session_Initiation_Protocol),但使用原生 Tinode 消息传输。 注意: - 所有通信都由 Tinode 服务器代理。 - 客户端到服务器事件通过 `{note}` 消息分发,设置通话的 `topic` 和 `seq` 字段。 - 服务器到客户端数据通过 `me` 话题的 `{info}` 消息路由,设置通话的 `src`(通话话题)和 `seq` 字段(和/或在数据推送通知中)。 - 假设 Alice 和 Bob 都可能有多个设备。 ## 详情 ### 通话阶段 流程可分为 4 个阶段: * 步骤 1-5: 通话发起 * 步骤 6-7: 通话接听 * 步骤 8-15: 元数据交换 * 步骤 16-17: 通话终止 ```mermaid sequenceDiagram participant A as Alice participant S as Tinode 服务器 participant B as Bob rect rgb(212, 242, 255) Note over A: Alice 发起通话 A->>S: 1. {pub head:webrtc=started} S->>A: 2. {ctrl params:seq=123} S->>+B: 3. {info seq=123 event=invite} S-->>B: 或 {data seq=123 head:webrtc=started}
推送通知 B->>-S: 4. {note seq=123 event=ringing} S->>A: 5. {info seq=123 event=ringing} end Note over S: Bob 的客户端响铃
等待 Bob 接听 rect rgb(212, 242, 255) Note over B: Bob 接听通话 B->>S: 6. {note seq=123 event=accept} S->>A: 7a. {info seq=123 event=accept} S->>B: 7b. {info seq=123 event=accept} S-->>B: {data seq=124 head:webrtc=accepted,replace=123} S-->>A: {data seq=124 head:webrtc=accepted,replace=123} end Note over S: 通话已接听,端元数据交换 A->>S: 8. {note seq=123 event=offer} S->>+B: 9. {info seq=123 event=offer} B->>-S: 10. {note seq=123 event=answer} S->>A: 11. {info seq=123 event=answer} rect rgb(212, 242, 255) Note over S: ICE 候选交换 loop A->>S: 12. {note seq=123 event=ice-candidate} S->>B: 13. {info seq=123 event=ice-candidate} B->>S: 14. {note seq=123 event=ice-candidate} S->>A: 15. {info seq=123 event=ice-candidate} end end Note over S: 通话已建立
对话进行中 rect rgb(212, 242, 255) Note over S: 通话终止 alt A->>S: 16a. {note seq=123 event=hang-up} B->>S: 16b. {note seq=123 event=hang-up} end alt S->>B: 17a. {info seq=123 event=hang-up} S->>A: 17b. {info seq=123 event=hang-up} end S-->>B: {data seq=125 head:webrtc=finished,replace=123} S-->>A: {data seq=125 head:webrtc=finished,replace=123} end ``` ### 通话建立与终止步骤 #### 通话发起 1. `Alice` 通过发布视频通话消息(带 `webrtc=started` 头)发起通话 2. 服务器回复 `{ctrl}` 消息,包含通话的 `seq` id。 3. 服务器将 `invite` 事件消息路由到 `Bob`(所有客户端)。 - 此外,服务器向 `Bob` 发送包含 `webrtc=started` 字段的数据推送通知。 - 收到以上任一消息后,`Bob` 显示来电通话 UI。 4. `Bob` 回复 `ringing` 事件。 5. 服务器将 `ringing` 事件转发给 `Alice`。后者现在播放振铃音。 - 注意 `Alice` 可能收到多个 `ringing` 事件,因为 `Bob` 的每个实例分别确认收到通话邀请。 - `Alice` 和服务器将等待服务器配置的超时时间,等待 `Bob` 接听然后挂断。 - 此时,通话正式**已发起**。 #### 通话接听 6. `Bob` 通过发送 `accept` 事件接听通话。 7. (a) 和 (b): 服务器将 `accept` 事件路由到 `Alice` 和 `Bob`。 - 此外,服务器广播通话数据消息的替换消息,带 `webrtc=accepted` 头。 - 替换消息的推送通知也会发送。 - `Bob` 的会话(除接听通话的那个)可以静默关闭来电通话 UI。 - 此时,通话正式**已接听**。 #### 元数据交换 8. `Alice` 发送包含 SDP 载荷的 `offer` 事件。 9. 服务器将 `offer` 路由给 `Bob`。 10. 收到 `offer` 后,`Bob` 回复包含 SDP 载荷的 `answer` 事件。 11. 服务器将 `Bob` 的 `answer` 事件转发给 `Alice`。 步骤 12-15 是 `Alice` 和 `Bob` 之间的 Ice 候选交换。 此时通话正式**已建立**。`Alice` 和 `Bob` 可以互相看到和听到。 #### 通话终止 16. `Alice` 向服务器发送 `hang-up` 事件。 17. 服务器将 `hang-up` 事件路由给 `Bob`。 此外,服务器广播通话数据消息的替换消息,带 `webrtc=finished` 头。 替换消息的推送通知也会发送。