搞懂 P2P 技术 (3) - WebRTC x AWS x KVS

WebRTC

全名 Web Real-Time Communication,是一个支援网页浏览器进行即时语音对话或影片对话的 API

WebRTC Wiki

WebRTC 的底层就是使用 ICE 来进行 P2P 打洞

Signaling Server

信令服务器,用来交换双方的 SDP 及 Ice candidate 来完成 P2P 打洞

实作 Signaling Server

WebRTC 没有明确定义如何实作 Signaling Server,主要原因在於如果双方一开始就知道对方的资讯,那其实就不需要 Signaling Server 来交换资讯

实作一个 Signaling Server 方式有很多种,可以用 HTTP 协议也可以用 WebSocket 协议,只要能顺利将双方的资讯做交换即可

SDP (Session Description Protocol)

会话描述协议(Session Description Protocol 或简写 SDP)描述的是流媒体的初始化参数。此协议由 IETF 发表为 RFC 2327

SDP 格式

v=0
o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
s=SDP Seminar
i=A Seminar on the session description protocol
u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
[email protected] (Mark Handley)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 31
m=application 32416 udp wb
a=orient:portrait
  • v=协议版本
  • o=发起者的 Session、Session ID 及 Session 版本
  • s=Session 名字
  • i=Session 资讯
  • u=有关会议资讯的 url
  • e=Email
  • p=手机号码
  • c=连线资讯
  • t = Session 活动时间
  • m = 媒体资讯 ((media) (port) (transport) (fmt list))
  • a = 媒体属性

Ice Candidate

Ice Candidate 描述 WebRTC 能与 远程设备通讯所需的协议和路由,启动 WebRTC P2P 後,通常会在连接的每一端提供多个 IceCandidate,直到绝定最佳线路达成为止.

{
  "sdpMLineIndex": 0,
  "sdpMid": "",
  "candidate": "a=candidate:2999745851 1 udp 2113937151 192.168.56.1 51411 typ host generation 0"
}

WebRTC Flow

p2p_webrtc

  1. 双方 Peer 先连上 Signaling Server
  2. PeerA 取得自身 SDP 并呼叫 setLocalDescription
  3. PeerA 将 SDP 传给 Signaling Server
  4. Signaling Server 将 PeerA 的 SDP 送给 PeerB
  5. PeerB 呼叫 setRemoteDescription 将 PeerA 的 SDP 写入
  6. PeerB 取得自身 SDP 并呼叫 setLocalDescription
  7. PeerB 将 SDP 传给 Signaling Server
  8. Signaling Server 将 PeerB 的 SDP 送给 PeerA
  9. PeerA 呼叫 setRemoteDescription 将 PeerB 的 SDP 写入
  10. PeerA 向 Stun server 询问 public IP
  11. Stun server 回应 public IP
  12. PeerA 向 TURN server 询问 relay 资讯 (relay ip/port)
  13. TURN server 回应 relay 资讯
  14. PeerA 将 Ice candidates 传给 Signaling Server
  15. Signaling Server 将 PeerA 的 Ice candidates 送给 PeerB
  16. PeerB 呼叫 setRemoteIceCandidate 将 PeerA 的 Ice candidates 写入
  17. PeerB 向 Stun server 询问 public IP
  18. Stun server 回应 public IP
  19. PeerB 向 TURN server 询问 relay 资讯 (relay ip/port)
  20. TURN server 回应 relay 资讯
  21. PeerB 将 Ice candidates 传给 Signaling Server
  22. Signaling Server 将 PeerB 的 Ice candidates 送给 PeerA
  23. PeerA 呼叫 setRemoteIceCandidate 将 PeerB 的 Ice candidates 写入
  24. P2P 通道建立完成

AWS KVS (Amazon Kinesis Video Streams)

Amazon Kinesis Video Streams 以全受管功能提供符合标准的 WebRTC 实作。您可以使用 Amazon Kinesis Video Streams and WebRTC 安全地即时串流媒体,或在任何摄影机 IoT 装置与符合 WebRTC 标准的行动或 Web 播放器之间,执行双向音讯或视讯互动。因为是全受管功能,您不需要建置、执行或扩展任何与 WebRTC 相关的云端基础设施,例如讯号或媒体转送服务器,即可在应用程序和装置之间安全地串流媒体。

简单来说 KVS 就是帮你把 STUN, TURN, Signaling Server 加密权限验证等等都实作了,WebRTC 的部分跟 KVS 是完全独立的,你也可以选择自己架设 STUN, TURN, Signaling Server 搭配 Google WebRTC 也能成功串流.

KVS 的 Signaling server 是用 WebSocket 去实作的

注意: WebSocket 与 Socket.IO 是不是一样的,Socket.IO 是根据 Websocket 协议去实作,Socket.IO 有自己的通讯格式,请不要拿 Socket.IO 套件去串接 KVS,会失败,有兴趣可以参考这篇 【笔记】Socket,Websocket,Socket.io 的差异

成果

理解这些 P2P 相关的知识,我们就可以很清楚的实作每一步骤,出错时也能清楚哪一部分出错,甚至是替换 Stun / TURN / signaling server 都没问题,下面贴一下成果图

ios_webrtc
android_webrtc

踩雷补充

  • 在串接 AWS KVS 时,AWS Android 的 sample code 是使用 tyrus 套件连 signaling server,但此套件在旧版有一些 SSL 问题有机会失败,所以我把 tyrus 换成 okhttp 去连 signaling server,但一直连不上 403 Forbidden,iOS 用 starscream 连线正常,後来比对两平台 URL 发现,Android 的会多做一次 url encode,在 tyrus 没问题,但在 okhttp 上会有问题 (解法请参考 : https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-android/issues/74)

总结

P2P 的基本观念大致就到这边,如果想要更深入的理解 P2P 的朋友,可以看参考资源栏中的文章,或直接看 RFC ,里面会说到每个协议的格式细节.

参考资源


<<:  搞懂 P2P 技术 (2) - STUN x TURN x ICE

>>:  【C#】物件导向的六个原则

Flask 防止 injection

在写好flask 服务之後,可能会将服务给弱点分析软件进行扫描, 之後会显示出一些高风险的漏洞, 而...

Day 27 (Js)

1.变数不影响他人的方式(合作时要用) (1)把自己的计划包起来,变数执行完之後就舍弃 IIFE =...

DAY 26- 分叉 Fork

「———≡」 分叉 网路上的传播是有时间误差的,也就是说如果今天 A 矿工成功挖到矿,并把挖到的区块...

【资料结构】读档相关 12/18更

二维阵列的一维读入法 #include <math.h> #include <st...

涂鸦冠军岛 - Google 专为东京奥运打造的线上小游戏~

打开 Google Chrome, 首页就可以看到罗~ ...