日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

调用ice服务器_Nodejs+socket.io搭建WebRTC信令服务器

發布時間:2025/3/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 调用ice服务器_Nodejs+socket.io搭建WebRTC信令服务器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

我們在學習 WebRTC 時,首先要把實驗環境搭建好,這樣我們就可以在上面做各種實驗了。

對于 WebRTC 來說,它有一整套規范,如使它使用的接口、使用SDP進行媒體協商、通過ICE收集地址并進行連通性檢測等等。除此之外,WebRTC還需要房間服務器將多端聚集到一起管理,以及信令服務器進行信令數據交換(如媒體描述信息SDP的交換,連接地址的交抽換等),但在WebRTC的規范中沒有對這部分內容進行規定,所以需要由用戶自己處理。

你可以根據自己的喜好選擇服務器(如 Apache,Nginx 或 Nodejs),我今天將介紹如何使用 Nodejs 來搭建信令服務器。

為什么選擇 Nodejs

Apache、Nginx和Nodejs都是非常成熟的Web服務器,Nginx 可以說是的性能是最好的Web服務器了。但從未來的發展來說,Nodejs可能會更有優勢。

現在以Chrome為代表的瀏覽器的功能越來越強大,以前認為通過瀏覽器不可能完成的事兒,現在它都可以輕松實現。H5、 WebSocket的出現以及現在WebRTC的加入,讓大家越來越覺得以后的瀏覽器可以說是“無所不能”。因此,推動 JavaScript 語言的發展越來越迅速。這可以從現在 JavaScript 技術的火爆,以及各種層疊不窮JS FrameWork的出現得以印證。

而 Nodejs 的最大優點即是可以使用 JS 語言開發服務器程序。這樣使得大量的前端同學可以無縫的轉到服務器開發,甚至有可能前后端使用同一套代碼實現。對于這一點我想無論是對個人還是對于企業都是具大的誘惑。

  • 一方面 JS 語言的簡單性可以方便開發出各種各樣功能的服務端程序。
  • 更可貴的是 Nodejs 的生態鏈非常的完整,有各種各樣的功能庫。你可以根據自己的需要通過安裝工具 NPM 快速的安裝,這也使它也得到了廣大開發者的喜歡。

Nodejs 現在是非常流行的 Web 服務器,它在服務器端使用 V8(JavaScript)引擎,通過它解析 JS 腳本來控制服務器的行為。這對于廣大的 JS 同學來說真是太幸福了,在10年前還很難想像可以通過 JS 腳本語言來寫服務器程序。

當然,如果你想對Nodejs作能力拓展的話,還是要寫C/C++庫,然后加載到 Nodejs 中去。

Nodejs的基本原理

Nodejs的工作原理如上圖所示, 其核心是 V8 引擎。通過該引擎,可以讓 js 調用 C/C++方法 或 對象。相反,通過它也可能讓 C/C++ 訪問 javascript 方法和變量。

Nodejs 首先將 JavaScript 寫好的應用程序交給 V8 引擎進行解析,V8理解應用程序的語義后,再調用 Nodejs 底層的 C/C++ API將服務啟動起來。 所以 Nodejs 的強大就在于 js 可以直接調用 C/C++ 的方法,使其能力可以無限擴展。

以開發一個 HTTP 服務為例,Nodejs 打開偵聽的服務端口后,底層會調用 libuv 處理該端口的所有 http 請求。其網絡事件處理如下圖所示:

當有網絡請求過來時,首先會被插入到一個事件處理隊列中。libuv會監控該事件隊列,當發現有事件時,先對請求做判斷,如果是簡單的請求,就直接返回響應了;如果是復雜請求,則從線程池中取一個線程進行異步處理;

線程處理完后,有兩種可能:一種是已經處理完成,則向用戶發送響應;另一種情況是還需要進一步處理,則再生成一個事件插入到事件隊列中等待處理;事件處理就這樣循環往復下去,永不停歇。

兩個 V8 引擎

如上圖所示,在我們使用 Nodejs之后實際存在了兩個 V8 引擎。一個V8用于解析服務端的 JS 應用程序,它將服務啟動起來。另一個 V8 是瀏覽器中的 V8 引擎,用于控制瀏覽器的行為。

對于使用 Nodejs 的新手來說,很容易出現思維混亂,因為在服務端至少要放兩個 JS 腳本。其中一個是服務端程序,控制 Nodejs 的行為,它由 Nodejs 的V8引擎解析處理;另一個是客戶端程序,它是要由瀏覽器請求后,下發到瀏覽器,由瀏覽器中的 V8 引擎進行解析處理。如果分不清這個,那麻煩就大了。

安裝 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 命令類似,是專門用來管理各種依賴庫的。

在它們沒有出現之前,我們要安裝個包特別麻煩。以Linux為例,假設要安裝一個工具,其基本步驟是:

  • 先將這個工具的源碼下載下來。
  • 執行./configure 生成Makefile 文件。
  • 執行 make 命令對其進行編譯。
  • 最后,執行 make install 將其安裝到指定目錄下。
  • 如果編譯過程中發現有依賴的庫,則要對依賴庫執行前面的4步,也就是先將依賴庫安裝好,然后再來安裝該工具。

大家可以看到,以前在Linux下安裝個程序或工具是多么的麻煩。

Linux 有了apt 之后,一切都變得簡單了。我們只要執行 apt install xxx 一條命令就好了,它會幫你完成上面的一堆操作。

對于 Nodejs的安裝包也是如此,NPM 就是相當于 Linux 下的 apt,它的出現大大提高了人們的工作效率。

NPM 的安裝像安裝 Nodejs 一樣簡單:

在Ubuntu下執行:

apt install npm

或在Mac下執行:

brew install npm

http://socket.io

此次,我們使用 Nodejs 下的 http://socket.io 庫來實現 WebRTC 信令服務器。http://socket.io特別適合用來開發WebRTC的信令服務器,通過它來構建信令服務器特別的簡單,這主要是因為它內置了房間 的概念。

上圖是 http://socket.io 與 Nodejs配合使用的邏輯關系圖, 其邏輯非常簡單。http://socket.io 分為服務端和客戶端兩部分。服務端由 Nodejs加載后偵聽某個服務端口,客戶端要想與服務端相連,首先要加載 http://socket.io 的客戶端庫,然后調用 io.connect();就與服務端連上了。

需要特別強調的是 http://socket.io 消息的發送與接收。http://socket.io 有很多種發送消息的方式,其中最常見的有下面幾種,是我們必須要撐握的:

  • 給本次連接發消息
    socket.emit()
  • 給某個房間內所有人發消息http://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下的 http://socket.io 來構建的一個服務器:

這是客戶端代碼,也就是在瀏覽器里執行的代碼。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 與服務端通訊。

下面是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); //偵聽 2013io.sockets.on('connection', (socket) => {// convenience function to log server messages to the clientfunction 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 clientssocket.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 安裝 http://socket.io 和 node-static,安裝方法如下:

npm install socket.io npm install node-static

啟動服務器并測試

通過上面的步驟我們就使用 http://socket.io 構建好一個服務器,現在可以通過下面的命令將服務啟動起來了:

node server.js

如果你是在本機上搭建的服務,則可以在瀏覽器中輸入 localhost:2013 ,然后新建一個tab 在里邊再次輸入localhost:2013 。此時,打開控制臺看看發生了什么?

在Chrome下你可以使用快捷鍵 Command-Option-J或Ctrl-Shift-J的DevTools訪問控制臺。

小結

以上我向大家介紹了 Nodejs 的工作原理、Nodejs的安裝與布署,以及如何使用要 sokcet.io 構建 WebRTC 信令消息服務器。socket.io 由于有房間的概念所以與WebRTC非常匹配,用它開發WebRTC信令服務器非常方便。

另外,在本文中的例子只是一個簡單例子并沒有太多的實際價值。在我的 《WebRTC實時互動直播技術入門與實戰》課中,會以上面的例子為基礎,教給大家如何一步一步的實現 WebRTC信令服務器,并與 WebRTC 配合實現1對1音視頻實時互動直播系統。

課程地址

WebRTC實時互動直播技術入門與實戰

謝謝!

總結

以上是生活随笔為你收集整理的调用ice服务器_Nodejs+socket.io搭建WebRTC信令服务器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。