通過WebRTC進行實時通訊-建立信令服務交換資料

目錄
- ofollow,noindex">介紹
- 概述
- 獲取樣例程式碼
- 從webcam獲取視訊流
- 通過RTCPeerConnection傳輸視訊
- 使用RTCDataChannel交換資料
我們將學習哪些內容
在這一步,你將發現如何做:
npm
本步驟的完整版本在 step-04目錄下。
概念
為了建立並維護一個WebRTC呼叫,WebRTC端點需要交換 metadata:
- 候選者(網路)資訊
-
**Off**
和**Answer**
提供了關於媒體的資訊,如解析度和解碼器。
換句話說,交換metadata需要在點對點傳輸音訊、視訊或資料之前。這個過程稱之為信令。
在前一步,傳送者與接收者的 RTCPeerConnection物件在同一個頁面上,信令在兩個物件間傳遞metadata是一件簡單的事情。
在真實世界的應用程式中,在web頁面上的傳送者與接收者的 RTCPeerConnection物件執行在不同的裝置上,所以你說需要給他們提供一種通訊metadata的方法。
為了這一點,我們使用信令服務:一種能在WebRTC端點之間傳遞訊息的服務。真實的訊息是明文的:字元化的 javascript 物件。
前提條件:安裝Node.js
為了下一步的試驗(step-04 到 step-06),你需要使用 Node.js在本地執行一個服務。
你可以從這個 連結 下載並安裝 Node.js 或 通過你喜歡的 包管理 。
安裝好後,你能引入下一步需要的依賴(執行 npm install),以及執行一個小的本地服務進行這個實驗(執行 node index.js)。這些命令在後面說明我們需要的時候再說明。
關於 App
WebRTC使用客戶端的 JavaScript API, 但在直實世界裡也使用信令(訊息)伺服器,以及 STUN 和 TURN服務。你能在[這裡] here
找到更多資訊。
在這一步,你將構建一個簡單的 Node.js信令服務,使用 Node.js Socket.IO 模組和 JavaScript 庫。Node.js和 Socket.IO的經驗是有用的,但不是關鍵的; 訊息元件非常簡單。
選擇正確的信令服務
這個實驗使用 Socket.IO 作為信令服務。
Socket.IO設計成使它直接構建一個交換訊息的服務, 並且 Socket.IO適合用於學習 WebRTC信令,因為它內部有放房間的概念。
然而,對一個產品服務,有更好的選擇。看 How to Select a Signaling Protocol for Your Next WebRTC Project .
在這個例子中,服務(Node.js應用)在index.js中實現。而執行在它上邊的客戶端(web應用)在index.html中實現。
在本步驟中的 Node.js應用有兩上作務
首先,它充當訊息中繼:
socket.on('message', function (message) { log('Got message: ', message); socket.broadcast.emit('message', message); });
其次,它管理WebRTC視訊聊天'房間':
if (numClients === 0) { socket.join(room); socket.emit('created', room, socket.id); } else if (numClients === 1) { socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready'); } else { // max two clients socket.emit('full', room); }
我們的簡單 WebRTC應用允許最多兩上人在房間裡。
HTML & JavaScript
更新 index.html,它看看起來像下面這樣:
<!DOCTYPE html> <html> <head> <title>Realtime communication with WebRTC</title> <link rel="stylesheet" href="css/main.css" /> </head> <body> <h1>Realtime communication with WebRTC</h1> <script src="/socket.io/socket.io.js"></script> <script src="js/main.js"></script> </body> </html>
在此步驟中,您不會在頁面上看到任何內容:所有日誌記錄都在瀏覽器控制檯上完成。
(要在Chrome中檢視控制檯,請按Ctrl-Shift-J或Command-Option-J,如果您使用的是Mac。)
用以下內容替換js / main.js:
'use strict'; var isInitiator; window.room = prompt("Enter room name:"); var socket = io.connect(); if (room !== "") { console.log('Message from client: Asking to join room ' + room); socket.emit('create or join', room); } socket.on('created', function(room, clientId) { isInitiator = true; }); socket.on('full', function(room) { console.log('Message from client: Room ' + room + ' is full :^('); }); socket.on('ipaddr', function(ipaddr) { console.log('Message from client: Server IP address is ' + ipaddr); }); socket.on('joined', function(room, clientId) { isInitiator = false; }); socket.on('log', function(array) { console.log.apply(console, array); });
建立 Socket.IO並執行在 Node.js上
在HTML檔案中,您可能已經看到您正在使用Socket.IO檔案:
<script src="/socket.io/socket.io.js"></script>
在工作目錄的頂層建立一個名為package.json的檔案,其中包含以下內容:
{ "name": "webrtc-codelab", "version": "0.0.1", "description": "WebRTC codelab", "dependencies": { "node-static": "^0.7.10", "socket.io": "^1.2.0" } }
這是一個應用程式清單,它告訴Node Package Manager(npm)要安裝哪些專案依賴項。
要安裝依賴項(例如/socket.io/socket.io.js),請在工作目錄的命令列終端中執行以下命令:
npm install
您應該看到一個安裝日誌,結束如下所示:

如您所見,npm已經安裝了package.json中定義的依賴項。
在工作目錄的頂層(而不是在js目錄中)建立一個新檔案index.js並新增以下程式碼:
'use strict'; var os = require('os'); var nodeStatic = require('node-static'); var http = require('http'); var socketIO = require('socket.io'); var fileServer = new(nodeStatic.Server)(); var app = http.createServer(function(req, res) { fileServer.serve(req, res); }).listen(8080); var io = socketIO.listen(app); io.sockets.on('connection', function(socket) { // convenience function to log server messages on the client function log() { var array = ['Message from server:']; array.push.apply(array, arguments); socket.emit('log', array); } socket.on('message', function(message) { log('Client said: ', message); // for a real app, would be room-only (not broadcast) socket.broadcast.emit('message', message); }); socket.on('create or join', function(room) { log('Received request to create or join room ' + room); var clientsInRoom = io.sockets.adapter.rooms[room]; var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0; log('Room ' + room + ' now has ' + numClients + ' client(s)'); if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready'); } else { // max two clients socket.emit('full', room); } }); socket.on('ipaddr', function() { var ifaces = os.networkInterfaces(); for (var dev in ifaces) { ifaces[dev].forEach(function(details) { if (details.family === 'IPv4' && details.address !== '127.0.0.1') { socket.emit('ipaddr', details.address); } }); } }); });
從命令列終端,在工作目錄中執行以下命令:
node index.js
在瀏覽器中,開啟localhost:8080。
每次開啟此URL時,系統都會提示您輸入房間名稱。
要加入同一個房間,請每次選擇相同的房間名稱,例如“foo”。
開啟一個新標籤頁,然後再次開啟localhost:8080。
選擇相同的房間名稱。
在第三個選項卡或視窗中開啟localhost:8080。
再次選擇相同的房間名稱。
檢查每個選項卡中的控制檯:您應該從上面的JavaScript中看到日誌記錄。
點滴
- 可能有哪些替代訊息傳遞機制?使用“純”WebSocket可能遇到什麼問題?
- 擴充套件此應用程式可能涉及哪些問題?您是否可以開發一種方法來測試成千上萬的同時房間請求?
- 此應用使用JavaScript提示獲取房間名稱。找出一種從URL獲取房間名稱的方法。
例如localhost:8080 / foo會給房間名稱foo。
你學到了什麼
在此步驟中,您學習瞭如何
- 使用npm來安裝package.json中指定的專案依賴項
- 執行Node.js伺服器到伺服器靜態檔案。
- 使用socket.io在Node.js上設定訊息傳遞服務
- 用它來建立“房間”並交換訊息。
此步驟的完整版本位於step-04資料夾中。
瞭解更多
- Socket.io chat-example repo
- WebRTC in the real world: STUN, TURN and signaling
- The term 'signaling' in WebRTC
Next up
瞭解如何使用信令使兩個使用者建立對等連線。