通過WebRTC進行實時通信-建立信令服務交換數據

目錄

我們將學習哪些內容

在這一步,你將發現如何做:

  • 使用 npm安裝 package.json中指定的項目依賴
  • 運行 Node.js 服務,並使用靜態節點服務靜態文件
  • 在Node.js上使用 Socket.IO 建立消息服務
  • 使用它創建房間並交換消息

本步驟的完整版本在 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中看到日誌記錄。

點滴

  1. 可能有哪些替代消息傳遞機制?使用“純”WebSocket可能遇到什麼問題?
  2. 擴展此應用程序可能涉及哪些問題?您是否可以開發一種方法來測試成千上萬的同時房間請求?
  3. 此應用使用JavaScript提示獲取房間名稱。找出一種從URL獲取房間名稱的方法。
    例如localhost:8080 / foo會給房間名稱foo。

你學到了什麼

在此步驟中,您學習瞭如何

  • 使用npm來安裝package.json中指定的項目依賴項
  • 運行Node.js服務器到服務器靜態文件。
  • 使用socket.io在Node.js上設置消息傳遞服務
  • 用它來創建“房間”並交換消息。

此步驟的完整版本位於step-04文件夾中。

瞭解更多

Next up

瞭解如何使用信令使兩個用戶建立對等連接。

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