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.emit()
io.in(room).emit()
socket.to(room).emit()
socket.broadcast.emit()
消息又該如何接收呢?
S
: socket.emit('cmd’);
C
: socket.on('cmd',function(){...});
- 送了一個 command 命令,帶 data 數據
S: socket.emit(
'action'
, data); C: socket.on(
'action'
,
function
(data){...});
S: socket.emit(action,arg1,arg2); C: socket.on(
'action'
,
function
(arg1,arg2){...});
有了以上這些知識,咱們就能夠實現信令數據通信了。
搭建信令服務器
這是客戶端代碼,也就是在瀏覽器裏執行的代碼。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"消息。
進入到
server.js
所在的目錄,而後執行下面的命令。
npm
install
socket.io npm
install
node-
static
啓動服務器並測試
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