WebRTC-的-peer-connection-example

170 阅读2分钟

概述

WebRTC library 自带了一些例子和工具,可以用来测试和评估 WebRTC 的常用功能

代码位于 webrtc-checkout/src/examples/peerconnection 目录下,主要有如下文件

├── client
│   ├── conductor.cc
│   ├── conductor.h
│   ├── defaults.cc
│   ├── defaults.h
│   ├── flag_defs.h
│   ├── linux
│   │   ├── main.cc
│   │   ├── main_wnd.cc
│   │   └── main_wnd.h
│   ├── main.cc
│   ├── main_wnd.cc
│   ├── main_wnd.h
│   ├── peer_connection_client.cc
│   └── peer_connection_client.h
└── server
    ├── data_socket.cc
    ├── data_socket.h
    ├── main.cc
    ├── peer_channel.cc
    ├── peer_channel.h
    ├── server_test.html
    ├── utils.cc
    └── utils.h

基本拓扑结构如下

  1. 一个 pc(peerconnection) server,也就是一个简单的 web server 用来在两个 client 之间交换信令,比如 SDP, ICE candidate

  2. 两个 pc(peerconnection) client, 通过 直接连接进行音频和视频媒体数据的传输

PC server

先看服务器类,它相对比较简单,主要功能是信令交换.

server 代码比较简单,启动一个 HTTP server, 接受 client 的连接, 将接收的数据在 client 之间进行交换 两个 client 都连接到 server 上, 发送 HTTP 请求 ”/signin" , server 把它作为一个成员(ChannelMember)加到内存中的成员列表中(PeerChannel.members)

这里有一个蹩脚的设计, 由于 server 提供的是 Http 服务,它不会主动发起请求到 client 总是等 client 来要数据(/wait),server 发现有消息缓存在内部队列(ChannelMember.queue_)中,它才把消息以 HTTP 响应告诉 client.

如果使用的是双向的 websocket 协议,就没这么麻烦了,当然这只是一个示例,怎么简单怎么来。

  • 启动命令:
C:\webrtc-checkout\src\out\Default\peerconnection_server.exe --port=8888
classresponsibilitycollaborators
ListeningSocket侦听端口并接受新的连接DataSocket
DataSocket代表一个 HTTP 连接 ListeningSocket
ChannelMember代表一个连接到 server 上的一个端点DataSocket
PeerChannel代表一个传输通道,供其中的成员之间的通信ChannelMember

PC Client

client 相对麻烦一些,既要通过 server 彼此之间交换信令(sdp, candidate), 还要获取本地的音视频媒体流,发送到对端,接收远端传来的媒体流,在本地回放。

而且 client 还要处理 GUI 上与用户的交互

  • 启动命令
C:\webrtc-checkout\src\out\Default\peerconnection_client.exe --autoconnect

主要的流程

participant alice
participant server
participant bob
alice->>server: sign in
server-->>alice: alice's id
bob->>server: sign in
server-->>bob: bob's id, alice's name, id
alice->>server: wait
server-->>alice: bob's name, id
alice->>server: offer(sdp)
server-->>alice: ok
bob->>server: wait
server-->>bob: offer(sdp)
bob->>server: answer(sdp)
server-->>bob: ok
alice->>server: wait
server-->>alice: answer(sdp)
alice->>server: candidate
server-->>alice: ok
bob->>server: candidate
server-->>bob: ok
alice->>server: wait
server-->>alice: bob's candidate
bob->>server: wait
server-->>bob: alice's candidate
alice->>server: sign_out
server-->>alice:ok
bob->>server: sign out
server-->>bob: ok

通过以上的信令交互, Alice 和 Bob 交换了彼此的 SDP 和 Candidate, 这样就可以搭建 PeerConnection,以 RTP 来传输彼此的音视频数据了

participant main
participant ListeningSocket as ls
participant DataSocket as s
participant PeerChannel as clients
participant ChanndleMember as member

main->ls: Create()
main->ls: Listen(port)
main->clients: create
main->main: select
main->s: OnDataAvailable()
main->clients: lookup(socket)
alt IsPeeerConnection(s)
    
    alt !member
       main->clients: AddMember(s)
       clients->member: new
       clients->clients: BroadcastChangedState(...)
       clients->clients: HandleDeliveryFailures(...)
    
    else
       main->clients:IsTargetedRequest(s)
       alt it is target
         main->member: ForwardRequestToPeer(s, target)
         member->member: QueueResponse(...)
       else
         main->s: Send(200 | 500)
       end
    end

主要的类