譯:WebRTC視頻通信淺析

WebRTC可以進行p2p之間的通信,但是仍需要服務支持.
1. signaling服務: 客戶端之間交換元數據來建立通信.
2. 穿透NATs和防火牆.

在本文中,我們想你展示如何構建一個signaling服務,如何用STUN/TURN服務去做NATs穿透.另外,解釋WebRTC是如何進行多端通話的.以及如何利用VoIP/PSTN 建立通話.

什麼是信令服務(Signaling)?

信令是在協調溝通的過程,爲了讓WebRTC應用程序建立一個”通話”,客戶端之間要交換信令信息:

打開或關閉一個會話的控制信息錯誤信息媒體源數據,比如編碼解碼設置,帶寬和媒體類型關鍵數據,用於建立安全連接網絡數據,例如主機地址和端口.

信令服務是一個在客戶端間來回傳遞信息的機制.這個機制沒有在WebRTC中實現,需要我們自己創建它們.在說明幾種創建信令方法之前,先交代一下背景.

爲什麼WebRTC沒有指定信令?

爲了避免冗餘數據和保持最大的兼容性.在建立信令時WebRTC沒有指定一個標準的協議.


WebRTC設計思想是在完全控制媒體層部分,讓信令層儘量脫離應用,因爲很可能不同的應用在使用不同的協議.在這種模式下,需要交換的關鍵信息是多媒體的會話描述,它指定了必要的運輸和媒體配置信息. JSEP結構也避免了讓瀏覽器保存狀態信息,防止每次頁面重載,信令就會丟失. 所以把信令狀態保存到服務器中.

<img title="" class="keylink" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; cursor: pointer; display: block; height: 392.8px; list-style-image: none; list-style-position: outside; list-style-type: none; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 630px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; width: 630px;" alt="JSEP architecture" src="https://www.2cto.com/uploadfile/Collfiles/20160331/20160331091317497.png" kf="" ware="" vc="" "="" target="_blank">vczl1LTK/b7dLG9mZmVyus1hbnN3ZXLX8crYu+G7sMPoyvbQrdLpKFNEUCm9+NDQvbvB9y7I58/COjwvcD4NCjxwcmUgY2xhc3M9"brush:java;">v=0o=- 7614219274584779017 2 IN IP4 127.0.0.1s=-t=0 0a=group:BUNDLE audio videoa=msid-semantic: WMSm=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126c=IN IP4 0.0.0.0a=rtcp:1 IN IP4 0.0.0.0a=ice-ufrag:W2TGCZw2NZHuwlnfa=ice-pwd:xdQEccP40E+P0L5qTyzDgfmWa=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-levela=mid:audioa=rtcp-muxa=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQea=rtpmap:111 opus/48000/2

如果想了解SDP,可以查看IETF examples.
WebRTC這樣設計是爲了讓offer和answer端能夠在調整之前通過SDP協議設置好本地或遠程描述. 例如: preferAudioCodec()方法用來設置默認編解碼方式和比特.雖然SDP在JavaScript中難操作,以後可能用JSON代替,但是還是有一些優勢的.

RTCPeerConnection + 信令: offer, answer and candidate

RTCPeerConnection是WebRTC客戶端之間建立音視頻通信的API.
初始化RTCPeerConnection需要兩個步驟:

確定本地媒體條件,如:分辨率,編解碼方式.這些是offer和answer所需的原始數據. 獲得潛在應用的主機地址,即candidate.

一旦本地數據確定,就必須通過信令機制與遠端進行對等交換.
假設Alice呼叫Eve.下面詳細描述offer/answer機制.

Alice創建一個RTCPeerConnection對象, Alice用此對象的createrOffer()創建一個offer.並調用setLocalDescription()設置本地描述offer.(如:分辨率和編解碼方式) Alice把offer通過信令機制發送給Eva. Eva調用setRemoteDescription()方法傳入offer,來告訴她的PeerConnection對象遠端Alice的配置描述. 之後Eva會調用creatAnswer(),如果成功就會返回一個對應的本地session描述,即answer.(如果不成功,表示Eva沒有Alice的offer對應的本地設置) Eva根據生成的answer通過setLocalDescription()設置本地的描述. 然後用信令機制發送序列化後的answer返回給Alice. Alice根據Eva的answer調用setRemoteDescription()設置對方的描述.

至此,Alice和Eva都設置了本地及對方的描述,
接下來還需要交換網絡信息.”finding candidates”是指用ICE framework尋找網絡接口和端口的過程:

Alice用onlceCandidate handler 創建一個RTCPeerConnection對象. 當網絡candidates有效時這個handler會被調用. 在這個handler裏,Alice通過信令機制發送序列化的candidates數據給Eva. 當Eva從Alice獲得candidate信息,她會調用addIceCandidate()去給對方描述添加candidate.

JSEP 支持ICE Candidate Trickling(允許呼叫者在首次初始化offer後,可以逐步發送candidate給被呼叫者,這樣讓被呼叫者可以馬上開始設置連接,而不用等到所有candidates到達)

WebRTC的信令編碼

下面是一個W3C 代碼範例,概括了完整的信令流程.假設已經有了信令機制:SignalingChannel. 下面進行詳細討論.

var signalingChannel = new SignalingChannel();
var configuration = {
  'iceServers': [{
    'url': 'stun:stun.example.org'
  }]
};
var pc;

//調用 start()  啓動

function start() {
  pc = new RTCPeerConnection(configuration);

  // send any ice candidates to the other peer
  pc.onicecandidate = function (evt) {
    if (evt.candidate)
      signalingChannel.send(JSON.stringify({
        'candidate': evt.candidate
      }));
  };

  // let the 'negotiationneeded' event trigger offer generation
  pc.onnegotiationneeded = function () {
    pc.createOffer(localDescCreated, logError);
  }

  // once remote stream arrives, show it in the remote video element
  pc.onaddstream = function (evt) {
    remoteView.src = URL.createObjectURL(evt.stream);
  };

  // get a local stream, show it in a self-view and add it to be sent
  navigator.getUserMedia({
    'audio': true,
    'video': true
  }, function (stream) {
    selfView.src = URL.createObjectURL(stream);
    pc.addStream(stream);
  }, logError);
}

function localDescCreated(desc) {
  pc.setLocalDescription(desc, function () {
    signalingChannel.send(JSON.stringify({
      'sdp': pc.localDescription
    }));
  }, logError);
}

signalingChannel.onmessage = function (evt) {
  if (!pc)
    start();

  var message = JSON.parse(evt.data);
  if (message.sdp)
    pc.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
      // if we received an offer, we need to answer
      if (pc.remoteDescription.type == 'offer')
        pc.createAnswer(localDescCreated, logError);
    }, logError);
  else
    pc.addIceCandidate(new RTCIceCandidate(message.candidate));
};

function logError(error) {
  log(error.name + ': ' + error.message);
}

查看”單頁面”視頻聊天的例子simpl.info/pc,可以在控制檯log中看到offer/answer和candidate的交換過程.

Peer discovery

這裏有個問題: 我們如何找到別人進行會話?
對於電話來說我們有電話號碼查詢,而對於在線視頻聊天和通信,我們需要身份(id)和業務管理系統,以及一個讓用戶發起會話的手段. WebRTC apps需要一個讓用戶彼此表明自己可以開始或加入一個會話的信號.

WebRTC沒有定義成員發現機制(peer discovery),我們也不需要在這裏做設置.這個過程可以像發送一個URL地址那麼簡單,對於視頻聊天應用,例如talky.io等,你可以通過分享一個自定義連接邀請別人;開發人員做了一個實驗serverless-webrtc,可以讓webRTC用戶通過任何信息服務方式交換元數據,比如:IM,email;

如何創建一個信令服務

再次重申:webRTC中並沒有定義信令協議和機制的標準.無論你選擇什麼,你只需要一箇中介服務器來交換信令消息和客戶端間的應用程序數據.可悲的是,一個web應用不能簡單的在網絡喊”聯繫我,我的朋友”.

慶幸的是,信令的消息小,大部分的交換都是在呼叫開始的時候.
在測試apprtc.appspot.com和samduttion-nodertc.jit.su時,我們可以發現,一個視頻通話總共只有大約10KB的消息是由信令服務處理的.

除了相對寬鬆的帶寬要求,webRTC的信令服務也不會花費過多的進程和內存.因爲他們只需要交換消息和保留少量的的會話狀態數據(比如,哪個客戶端連接了).

信令機制不僅用來交換session元數據,也能用於應用程序數據通信,它只是一個消息傳遞服務.

服務端推送信息到客戶端

一個信令服務需要是雙向的:服務端到客戶端/客戶端到服務端. 雙向通訊雖然違反了HTTP的請求/回覆模式,但是有一些發展多年的技術,例如long polling(長時間問詢)用來從服務器發送數據給一個在瀏覽器中運行的web應用.

最近,EventSource API被廣泛應用,可以讓數據通過HTTP從服務端發送給瀏覽器. 有一個簡單的demo:simpl.info/es. EventSource是專門用於一個消息傳遞的方式,但它可以結合XHR 做成一個交換signaling消息的服務:從一個呼叫者傳遞一個消息,由XHR請求,推送給被呼叫者.

WebSocket是一種更自然的雙向通訊解決方法,設計爲全雙工客戶端-服務端通信(消息可以同時在兩個方向流動). 使用純WebSocket或者EventSource建立信令服務可以讓後端用多種Web框架實現這些API調用.

大約四分之三的瀏覽器支持WebSocket,更重要的是,所有支持WebRTC的移動或PC瀏覽器也支持WebSocket.TLS(安全傳輸協議)應該用於所有連接,以確保消息不會被截獲. 同時 reduce problems with proxy traversa.(關於更多的WebSocket和proxy traversal資料可以查詢WebRTC chapte和WebSocket cheat sheet)

apart.appspot.com的信令是通過Google App Engine Channel API完成的,這個API使用了Comet技術(長時間輪詢)讓信令推動App Engine端和web客戶端之間的通信.(這裏有個long-standing bug,關於App Engine 對WebSocket的支持.)這裏有個代碼演示在HTML5 Rocks WebRTC article.

還可以通過Ajax輪詢WebRTC服務端獲取信令傳遞消息.但這會產生很多冗餘請求,特別是在移動端. 即是已經建立了一個會話, 用戶仍然需要去多次輪詢signaing信息. 因爲會話可能被其他用戶更改或終止.<<WebRTC>>中就使用了這個例子,經過了優化輪詢頻率.

信令擴展

雖然一個signaling服務在每個客戶端只花費很少的帶寬和CPU,但是一個受歡迎的應用程序服務器可能會需要處理大量的信息和高併發數,所以一個完善的webRTC應用需要信令服務能處理這些負荷.

下面有些處理大數據量的高性能信息通信選擇:

XMPP,最初被稱爲Jabber: 一種被開發用於即是通訊的協議. 可以用來做signaling.服務端可以用egabberd和Opendire實現.JavaScript客戶端,例如Strophe.js使用BOSH去模仿雙向通訊流, 但由於各種原因,BOSH不像WebSocket那麼小了(Jingle是一種支持視頻和語音的XMPP擴展,WebRTC從libjingle庫使用網絡和傳輸組件). 使用像ZeroMQ,QpenMQ的開源庫.利用STOMO webSocket協議適用於網絡平臺. 使用支持WebSocket的商業雲服務平臺,如:Ousher,Kaazing和PubNub. 商業WebRTC平臺.

一個綜合的信息服務和庫列表.

基於Socket.io建立信令服務

下面代碼是個簡單的web應用程序,使用Socket.io建立的signaling. Socket.io可以輕易的創建一個用於交換信息的服務,它非常適合WebRTC的信令,因爲Socket.io是基於”rooms”的概念設計的. 這個demo不是一個產品級的服務,適合相對較少的用戶.

Socket.io通過下面的回調使用WebSocket:Adobe Flash Socket,AJAX long polling,AJAX multipart streaming,FOrever Iframe and JSONP polling.
它已經被移植到各種後端,最有名的是Node.下面的例子中我們也將使用.

這個demo沒有WebRTC,它只展示怎麼創建一個webapp的signaling.用控制檯查看log,瞭解用戶加入一個房間交換數發生了什麼,WebRTC codelab會一步步指示如何將這個示例集成到一個完整的webRTC視頻聊天應用中.你可以從step 5 of the codelab repo下載源碼或者在samdutton-nodertc.jit.su運行(兩個瀏覽器中打開).

這是客戶端的 index.html:


<script src='/socket.io/socket.io.js'></script><script src='js/main.js'></script>這是JavaScript 的main.js文件 ,客戶端引用.
var isInitiator;

room = prompt('Enter room name:');

var socket = io.connect();

if (room !== '') {
  console.log('Joining room ' + room);
  socket.emit('create or join', room);
}

socket.on('full', function (room){
  console.log('Room ' + room + ' is full');
});

socket.on('empty', function (room){
  isInitiator = true;
  console.log('Room ' + room + ' is empty');
});

socket.on('join', function (room){
  console.log('Making request to join room ' + room);
  console.log('You are the initiator!');
});

socket.on('log', function (array){
  console.log.apply(console, array);
});
完整服務端:
var static = require('node-static');
var http = require('http');
var file = new(static.Server)();
var app = http.createServer(function (req, res) {
  file.serve(req, res);
}).listen(2013);

var io = require('socket.io').listen(app);

io.sockets.on('connection', function (socket){

  // convenience function to log server messages to the client
  function log(){
    var array = ['>>> Message from server: '];
    for (var i = 0; i < arguments.length; i++) {
      array.push(arguments[i]);
    }
      socket.emit('log', array);
  }

  socket.on('message', function (message) {
    log('Got message:', message);
    // for a real app, would be room only (not broadcast)
    socket.broadcast.emit('message', message);
  });

  socket.on('create or join', function (room) {
    var numClients = io.sockets.clients(room).length;

    log('Room ' + room + ' has ' + numClients + ' client(s)');
    log('Request to create or join room ' + room);

    if (numClients === 0){
      socket.join(room);
      socket.emit('created', room);
    } else if (numClients === 1) {
      io.sockets.in(room).emit('join', room);
      socket.join(room);
      socket.emit('joined', room);
    } else { // max two clients
      socket.emit('full', room);
    }
    socket.emit('emit(): client ' + socket.id + ' joined room ' + room);
    socket.broadcast.emit('broadcast(): client ' + socket.id + ' joined room ' + room);
  });
});

(你不需要了解node-static,它指示讓服務器更簡單)

在本地主機上運行這個應用程序,你需要安裝:Node,socket.io 和node-sattic,可以在nodes.org下載Node,再安裝socket.io和node-static. 在程序目錄終端運行

npm install socket.io
npm install node-static

啓動服務器,在終端中輸入

node server.js

在瀏覽器中打開localhost:2013. 打開一個新標籤頁或在任何瀏覽器窗口再打開localhost:2013. 用控制檯看發生了什麼. 無論哪種信令方式,都要你的後端和客戶端應用提供類似的服務.

使用RTCDataChannel 信令

一個WebRTC會話必須要有一個signaling

然而,一旦兩端建立了連接,理論上RTCDataChannel可以接替信令通道,這可以減少信號延遲,RTCDataChannel會幫忙減少帶寬使用和進程開銷.可以看下面:

信令性能和擴展性:

RTCPeerConnection只有setLocalDescription()被調用後纔會收集candidates. 利用Trickle ICE:接受到candidates後立即調用addIceCandidate()

使用現成的信令服務

如果你不想用自己的,這裏有一些現成的webRTC signaling服務端,就像上面的例子使用socket.io,結合WebRTC和JavaScript庫:

webRTC.io:第一個WebRTC的抽想庫 esayRTC:一個完整的WebRTC包 Signalmaster:一個使用SimpleWebRTC JavaScript客戶端庫創建的signaling server.

如果你不想寫任何代碼,去找商業平臺:vLine,OpenTok,Asterisk.

信令安全

所有WebRTC組件都要強制加密

然而,信令機制不是WebRTC所定義的,所以信令的安全取決於你,如果一個攻擊者成功截獲信號,他們可以停止,重定向鏈接,改變或者注入內容.

一個牢固的信令最重要的是使用安全協議,HTTPS和WSS.可以確保不被非法攔截.
同時,也不要廣播信令信息,不然攻擊者可以使用相同的信令服務訪問其他來電用戶.

使用TLS 確保WebRTC應用安全.

信令交互完之後,使用ICE去處理NATs和防火牆對於元數據的信令

WebRTC應用可以使用中間服務,但實際的媒體和數據流在一個會話確立後,RTCPeerConnection 嘗試去直連p2p客戶端:在一個簡單的世界裏,每一個WebRTC端都有一個唯一的地址,這樣他可以與其他端交換數據,以便直接 通訊。

實際情況下,大多數設備都在一個或多個NAT層後面,有些有防毒軟件阻礙確定的端口和協議,還有很多在代理和公司的防火牆後面。防火牆和NAT實際上可能由一些類似家庭wifi路由器產生的。

WebRTC 可以使用ICE框架去克服真實世界的複雜網絡。爲了實現這個功能,你的應用必須傳ICE服務地址給RTCPeerConnection,如下所述。
ICE 試着尋找最佳路線去連接對方,它會並行的尋找所有可能性,然後選擇最有效的可行方式。
ICE首先會嘗試用設備系統或網卡獲取到的主機地址去建立連接;如果這個失敗了(設備在NATs後面就會)ICE從STUN服務器獲得外部的地址,如果這個也失敗了,就用TURN中轉服務器做通訊。
也就是說:

STUN服務器用來獲取外部網絡地址。如果失敗,使用TURN服務器作爲中繼服務器傳輸數據.

每一個TURN服務器都支持STUN:一個TURN服務器是由一個STUN服務器加上中繼功能。ICE也可以用來應付複雜的NAT設置:事實上,NAT的”打洞“可能需要除了公共IP之外的端口地址。

WebRTC應用在iceServers配置對象(RTCPeerConnection constructor)裏設置STUN and/or TURN服務器地址。

{
  'iceServers': [
    {
      'url': 'stun:stun.l.google.com:19302'
    },
    {
      'url': 'turn:192.158.29.39:3478?transport=udp',
      'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
      'username': '28224511:1379330808'
    },
    {
      'url': 'turn:192.158.29.39:3478?transport=tcp',
      'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
      'username': '28224511:1379330808'
    }
  ]
}

一旦RTCPeerConnection 有了這些信息,ICE會自動啓動:RTCPeerConnection 使用ICE框架計算出兩端間最佳路線,需要STUN和TURN服務器。

STUN

NATs會給它的設備提供一個內部網絡IP地址,但這個地址不能在外網使用,所以WebRTC沒辦法做連接,爲解決這個問題,WebRTC使用了STUN。STUN服務架設在外網,它有一個簡單的任務:獲取一個發送請求的設備(運行在NAT後邊的應用)的IP和端口,然後返回這個地址。

換句話說,應用使用STUN服務器發現它的外網IP和端口,這個過程確保了一個WebRTC端獲得它自己的公共地址,然後通過signaling機制發送這個信息給另一端,這樣就可以建立起一個直接連接.

STUN服務器不需要做太多工作和存儲太多東西,所以簡單的STUN服務器可以應付大量的請求。根據 webrtcstats.com的統計,使用STUN方式建立WebRTC通話的成功率有86%的。

TURN

RTCPeerConnection 會試着用UDP在兩端建立一個直連,如果失敗了,RTCPeerConnection 會改用TCP,如果這個也失敗了,TURN服務器會被作爲後備方案使用,作爲在兩端間中繼服務器。
所以:TURN是在兩端間中轉視頻/語音/數據 流,而不是發送數據。

TURN 有個公共地址,所以每個端即使在防火牆或者代理後面,也能訪問到。
TURN有個簡單的任務,中轉數據流,但不像STUN,TURN會花費大量帶寬。所有,TURN需要夠強壯。
這裏寫圖片描述
圖顯示了TURN的作用: 單純的STUN不起作用,客戶端就會轉向使用TURN.

部署 STUN and TURN servers

谷歌公佈了一個公共的STUN服務,stun.l.google.com:19302, apprtc.appspot.com用的就是這個。作爲一個產品級別的 STUN/TURN服務器,我們建議使用 rfc5766-turn-server,STUN 和TURN的源碼可以從code.google.com/p/rfc5766-turn-server獲取,這個鏈接也包括了部署的資料。A VM image for Amazon Web Services is also available.本社區也發佈了部署教程:部署教程一個可代替的TURN服務器是restrund,可以在source code 下載到,下面介紹在谷歌Compute Engine部署resrund的步驟:
1. Open firewall as necessary, for tcp=443, udp/tcp=3478
2. Create four instances, one for each public IP, Standard Ubuntu 12.06 image
3. Set up local firewall config (allow ANY from ANY)
4. Install tools:
sudo apt-get install make
sudo apt-get install gcc
5. Install libre from creytiv.com/re.html
6. Fetch restund from creytiv.com/restund.html and unpack
7. wget hancke.name/restund-auth.patch and apply with patch -p1 < restund-auth.patch
8. Run make, sudo make install for libre and resound
9. Adapt restund.conf to your needs (replace IP addresses and make sure it contains the same shared secret) and copy to /etc
10. Copy restund/etc/restund to /etc/init.d/
11. Configure restund:
Set LD_LIBRARY_PATH
Copy restund.conf to /etc/restund.conf
Set restund.conf to use the right 10. IP address
12. Run resound
13. Test using stund client from remote machine: ./client IP:port

多人會議

你可能要看一下Justin Uberti’s 提議的IETF標準:REST API for access to TURN Services

一個WebRTC應用可以使用多個RTCPeerConnection, 這樣每一個端就可以連接到其他段形成一個網絡. talk.io就是用這種方式實現的.對於少數用戶可以很好的工作牡丹石進程和帶寬消耗很大,尤其對於移動端.
全網狀拓撲結構:每個人都連接到每個人
全網狀拓撲結構:每個人都連接到每個人

在一個星型結構裏,一個WebRTC應用可以選擇一個端去分佈數據流給所有的用戶,你可以自己設計重新分配機制的服務和構造去實現中轉方式,webrtc.org提供了一個示例客戶端應用.

從Chrome31何Opera18開始,從一個RTCPeerConnection獲取的媒體流可以作爲另一個輸入: 這裏有個demosimpl.info/multi. 這樣可以保證更靈活的結構,因爲它允許web應用通過選擇哪個用戶可以連接可以控制一個通話路由,

Multipoint Control Unit

大量用戶通話,更好的解決方案是使用Multipoint Control Unit(MCU). 這是一個在大量參與者間分佈媒體的橋接服務器.MCUs 可以在一個視頻會議裏處理不同的分辨率,編解碼,幀速率. 對於多端會議,有很多需要考慮: 最重要的是,從多個源裏,怎麼顯示多個視頻和混合音頻. 雲平臺如vLine還試圖優化交通路由。

你可以去買一個MCU硬件或自己搭一個.
Cisco MCU背部有幾個開源的MCU硬件款可以選擇, 例如Licode生成的開源 MCU for WebRTC; OpenTok 平臺的Mantis.

突破瀏覽器: VoIP, telephones 和 messaging

WebRTC 的標準讓瀏覽器和不同設備不同平臺,例如手機或者一個視頻會議系統,進行通話稱爲可能。

SIP是一種信令協議,用來做VoIP和視頻系統。爲了讓WebRTC和SIP端通訊,WebRTC需要一個代理服務器去調解信令。信令一定會經過網關,但是一旦會話建立,視頻和語音就能在兩端傳輸。

PSTN,公共電話交換網絡,是舊式模擬電話的交換網絡。爲了WebRTC和電話進行通話,必須通過一個PSTN網關。同理,要讓WebRTC跟Jingle端(像IM客戶端)通訊,需要一箇中間XMPP服務器。Jingle作爲XMPP的擴展,用來實現視頻和語音能夠作爲信息服務:現在的WebRTC就是基於C++實現libjingle 庫發展來的,Jingle最初是Google Talk的技術。

一堆應用庫,平臺讓WebRTC能在實際中通訊:
sipML5:一個 開源的 JavaScript SIP 客戶端
jsSIP: JavaScript SIP庫
Phono: 開源JavaScript phone API, 作爲一個插件
Zingaya: 一個嵌入式電話部件
Twilio: 音頻和信息
Uberconference: 會議技術

sipML5 的開發者也開發了webrtc2sip的網關Tethr and Tropo have demonstrated a framework for disaster communications ‘in a briefcase’, using an OpenBTS cell to enable communications between feature phones and computers via WebRTC. Telephone communication without a carrier!

Find out more

WebRTC codelab: step-by-step instructions how to build a video and text chat application, using a Socket.io signaling service running on Node.

2013 Google I/O WebRTC presentation with WebRTC tech lead, Justin Uberti.

Chris Wilson’s SFHTML5 presentation: Introduction to WebRTC Apps.

The WebRTC Book gives a lot of detail about data and signaling pathways, and includes a number of detailed network topology diagrams.

WebRTC and Signaling: What Two Years Has Taught Us: TokBox blog post about why leaving signaling out of the spec was a good idea.

Ben Strong’s presentation A Practical Guide to Building WebRTC Apps provides a lot of information about WebRTC topologies and infrastructure.

The WebRTC chapter in Ilya Grigorik’s High Performance Browser Networking goes deep into WebRTC architecture, use cases and performance

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章