如何搭建WebRTC信令服務器


WebRTC 有一整套規范,如怎樣使用它的接口、使用SDP進行媒體協商、通過ICE收集地址並進行連通性檢測等等。除此之外,WebRTC還需要房間服務器將多端聚集到一起管理,以及信令服務器進行信令數據交換(如媒體描述信息SDP的交換,連接地址的交換等),但在WebRTC的規范中沒有對這部分內容進行規定,所以需要由用戶自己處理。
安裝 Nodejs
下面我們就來看看具體如何安裝 Nodejs。
安裝 Nodejs 非常的簡單:
在Ubuntu系統下執行:
apt install nodejs
或在Mac 系統下執行:
brew install nodejs
通過上面的步驟我們就將 Nodejs 安裝好了。我這里安裝的 Nodejs版本為: v8.10.0
安裝NPM
除了安裝 Nodejs 之外,我們還要安裝NPM(Node Package Manager),也就是 Nodejs 的包管理器。它就像Ubuntu下的 apt 或Mac 系統下的brew 命令類似,是專門用來管理各種依賴庫的。
對於 Nodejs的安裝包也是如此,NPM 就是相當於 Linux 下的 apt,它的出現大大提高了人們的工作效率。
NPM 的安裝像安裝 Nodejs 一樣簡單:
在Ubuntu下執行:
apt install npm
或在Mac下執行:
brew install npm
此次,我們使用 Nodejs 下的  socket.io 6  庫來實現 WebRTC 信令服務器。socket.io特別適合用來開發WebRTC的信令服務器,通過它來構建信令服務器特別的簡單,這主要是因為它內置了 房間  的概念。
socket.io.jpg 2308×895 139 KB
上圖是  socket.io 6  與 Nodejs配合使用的邏輯關系圖, 其邏輯非常簡單。 socket.io 6  分為服務端和客戶端兩部分 。服務端由 Nodejs加載后偵聽某個服務端口,客戶端要想與服務端相連,首先要加載  socket.io 6  的客戶端庫,然后調用  io.connect(); 就與服務端連上了。
需要特別強調的是  socket.io 6  消息的發送與接收。 socket.io 6  有很多種發送消息的方式 ,其中最常見的有下面幾種,是我們必須要撐握的:
  • 給本次連接發消息
socket.emit()
  • 給某個房間內所有人發消息
io.in(room).emit()
  • 除本連接外,給某個房間內所有人發消息
socket.to(room).emit()
  • 除本連接外,給所以人發消息
socket.broadcast.emit()
消息又該如何接收呢?
  • 發送 command 命令
S : socket.emit('cmd’); C : socket.on('cmd',function(){...});
  • 送了一個 command 命令,帶 data 數據
S: socket.emit( 'action' , data); C: socket.on( 'action' , function (data){...});
  • 發送了command命令,還有兩個數據
S: socket.emit(action,arg1,arg2); C: socket.on( 'action' , function (arg1,arg2){...});
有了以上這些知識,我們就可以實現信令數據通訊了。
搭建信令服務器
接下來我們來看一下,如何通過 Nodejs下的  socket.io 6  來構建的一個服務器:
這是客戶端代碼,也就是在瀏覽器里執行的代碼。index.html:
<!DOCTYPE html> < html > < head > < title > WebRTC client </ title > </ head > < body > < script src= '/socket.io/socket.io.js' ></ script > < script src= 'js/client.js' ></ script > </ body > </ html >
該代碼十分簡單,就是在body里引入了兩段 JS 代碼。其中,socket.io.js 是用來與服務端建立 socket 連接的。client.js 的作用是做一些業務邏輯,並最終通過 socket 與服務端通訊。
首先,在 server.js 目錄下創建  js  子目錄,然后在 js目錄下生成 client.js。
下面是client.js的代碼:
var isInitiator; room = prompt( 'Enter room name:' ); // 彈出一個輸入窗口 const socket = io.connect(); // 與服務端建立socket連接 if (room !== '' ) { // 如果房間不空,則發送 "create or join" 消息 console .log( 'Joining room ' + room); socket.emit( 'create or join' , room); } socket.on( 'full' , (room) => { // 如果從服務端收到 "full" 消息 console .log( 'Room ' + room + ' is full' ); }); socket.on( 'empty' , (room) => { // 如果從服務端收到 "empty" 消息 isInitiator = true; console .log( 'Room ' + room + ' is empty' ); }); socket.on( 'join' , (room) => { // 如果從服務端收到 “join " 消息 console.log('Making request to join room ' + room); console.log('You are the initiator!'); }); socket.on('log', (array) => { console.log.apply(console, array); });
在該代碼中:
  • 首先彈出一個輸入框,要求用戶寫入要加入的房間。
  • 然后,通過 io.connect() 建立與服務端的連接,
  • 根據socket返回的消息做不同的處理:
  • 當收到房間滿"full"時的情況;
  • 當收到房間空“empty"時的情況;
  • 當收到加入“join"時的情況;
以上是客戶端(也就是在瀏覽器)中執行的代碼。下面我們來看一下服務端的處理邏輯:
服務器端代碼,server.js:
const static = require ( 'node-static' ); const http = require ( 'http' ); const file = new ( static .Server)(); const app = http.createServer( function (req, res) { file.serve(req, res); }).listen( 2013 ); const io = require ( 'socket.io' ).listen(app); //偵聽 2013 io.sockets.on( 'connection' , (socket) => { // convenience function to log server messages to the client function log (){ const array = [ '>>> Message from server: ' ]; for ( var i = 0 ; i < arguments.length; i++) { array .push(arguments[i]); } socket.emit( 'log' , array ); } socket.on( 'message' , (message) => { //收到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' , (room) => { //收到 “create or join” 消息 var clientsInRoom = io.sockets.adapter.rooms[room]; var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0 ; //房間里的人數 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); //發送 "created" 消息 } else if (numClients === 1 ) { //如果房間里有一個人 io.sockets.in(room).emit( 'join' , room); socket.join(room); socket.emit( 'joined' , room); //發送 “joined”消息 } else { // max two clients socket.emit( 'full' , room); //發送 "full" 消息 } socket.emit( 'emit(): client ' + socket.id + ' joined room ' + room); socket.broadcast.emit( 'broadcast(): client ' + socket.id + ' joined room ' + room); }); });
在服務端引入了  node-static  庫,使服務器具有發布靜態文件的功能。服務器具有此功能后,當客戶端(瀏覽器)向服務端發起請求時,服務器通過該模塊獲得客戶端(瀏覽器)運行的代碼,也就是上我面我們講到的 index.html 和 client.js 並下發給客戶端(瀏覽器)。
服務端偵聽 2013 這個端口,對不同的消息做相應的處理:
  • 服務器收到 message 消息時,它會直接進行廣播,所有連接到該服務器的客戶端都會收收廣播的消息。
  • 服務端收到 “create or join”消息時,它會對房間里有人數進行統計,如果房間里沒有人,則發送"created" 消息;如果房間里有一個人,發送"join"消息和“joined"消息;如果超過兩個人,發送"full"消息。
要運行該程序,需要使用 NPM 安裝  socket.io 6  和  node-static 1 ,安裝方法如下:
進入到  server.js  所在的目錄,然后執行下面的命令。
npm install socket.io npm install node- static
啟動服務器並測試
通過上面的步驟我們就使用  socket.io 6  構建好一個服務器,現在可以通過下面的命令將服務啟動起來了:
node server.js
如果你是在本機上搭建的服務,則可以在瀏覽器中輸入 localhost:2013 ,然后新建一個tab 在里邊再次輸入localhost:2013 。此時,打開控制台看看發生了什么?
小結
以上我向大家介紹了 Nodejs 的工作原理、Nodejs的安裝與布署,以及如何使用  要sokcet.io 1  構建 WebRTC 信令消息服務器。 socket.io 6  由於有房間的概念所以與WebRTC非常匹配,用它開發WebRTC信令服務器非常方便。
IM和視頻聊天的,可以參考下這個 https://github.com/starrtc/starrtc-android-demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM