天天看點

webRTC-NodeJS建立信令伺服器

作者:音視訊流媒體技術

前言

  • 本文取自《Learning WebRTC》
  • 建立完整的WebRTC應用,需要抛開用戶端的開發,轉而為服務端的開發

推薦閱讀

  • 《Learning WebRTC》

建構信令伺服器

  • 将不在同一個電腦中的兩個使用者連接配接起來
  • 伺服器的目的是通過網絡傳輸代替原先的信令機制
  • 對多個使用者做出回應:
    • 允許一方使用者呼叫另一方進而在雙方間建立WebRTC連接配接
    • 一旦使用者呼叫了另一方,伺服器将會在雙方間傳遞請求,應答和ICE候選路徑
webRTC-NodeJS建立信令伺服器

流程

  • 伺服器建立連接配接時的資訊流
  • 登陸伺服器開始,登入向伺服器端發送一個字元串形式的使用者辨別,確定沒有被使用
  • 登入進入,開始呼叫,通過使用對方的辨別碼發送請求
  • 發送離開資訊來終止連接配接
  • 此流程主要用來作為互相發送資訊的通道

注意

  • 由于發送信令的實作沒有任何規則,可以使用任意協定、技術或者模式

WebSockets

  • 建立WebRTC連接配接所需的步驟必須是實時的,最好使用WebSockets,不能使用WebRTC對等連接配接實時傳遞消
  • Socket以字元串和二進制碼方式雙向發送資訊
  • 完全依賴于WebSocket架構:Meteor JavaScript framework
  • npm安裝websocket:npm install ws
  • wscat:npm install wscat

server.js

const WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({port: 8888});

wss.on("connection", connection => {
    console.log("User connected");

    connection.on("message", message => {
        console.log("Got message:", message);
    });

    connection.send("hello world!")
});           
  • 監聽伺服器端的connection事件,當使用者與伺服器建立websocket連接配接時,會調用此,并有連接配接方的所有資訊
  • 安裝wscat進行測試:npm install -g ws, wscat -c ws://localhost:8888,或者前端測試
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        let websocket = new WebSocket("ws://localhost:8888");

    </script>
</body>
</html>           

相關學習資料推薦,點選下方連結免費報名,先碼住不迷路~】

【免費分享】音視訊學習資料包、大廠面試題、技術視訊和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點選加群免費領取~

webRTC-NodeJS建立信令伺服器

識别使用者

  • 典型的網絡應用中,伺服器需要一種方法來識别連接配接的使用者
  • 遵循唯一規則,讓每一個使用者有一個字元串形式的辨別,即使用者名

僅需一個id來辨別

const WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({port: 8888});

wss.on("connection", connection => {
    console.log("User connected");

    connection.on("message", message => {
        // console.log("Got message:", message);
        let data;

        try{
            data = JSON.parse(message);
        }catch(e) {
            console.log(e);
            data = {};
        }
    });

    connection.send("hello world!")
});           

完整的信令伺服器

const WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({port: 8888}),
    users = {};

wss.on("connection", connection => {
    console.log("User connected");

    connection.on("message", message => {
        // console.log("Got message:", message);
        let data, conn;

        try{
            data = JSON.parse(message);
        }catch(e) {
            console.log(e);
            data = {};
        }


        switch(data.type) {
            case "login":
                console.log("User logged in as", data.name);
                if(users[data.name]) {
                    sendTo(connection, {
                        type: "login",
                        success: false
                    });
                }else {
                    users[data.name] = connection;
                    connection.name = data.name;
                    sendTo(connection, {
                        type: "login",
                        success: true
                    });
                }
                break;
            
            case "offer":
                console.log("sending offer to:", data.name);
                conn = users[data.name];

                if(conn != null){
                    connection.otherName = data.name;
                    sendTo(conn, {
                        type: "offer",
                        offer: data.offer,
                        name: connection.name
                    });
                }
                break;

            case "answer":
                console.log("sending answer to:", data.name);
                conn = users[data.name];

                if(conn != null){
                    connection.otherName = data.name;
                    sendTo(conn, {
                        type: "answer",
                        answer: data.answer
                    })
                }
                break;

            case "candidate":
                console.log("sending to", data.name);
                conn = users[data.name];

                if(conn != null){
                    sendTo(conn, {
                        type: "candidate",
                        candidate: data.candidate
                    });
                }
                break;
            
            case "leave":
                console.log("Disconnected user from ", data.name);
                conn = users[data.name];
                conn.otherName = null;

                if(conn != null){
                    sendTo(conn, {
                        type: "leave"
                    });
                }
                break;
                
            default:
                sendTo(connection, {
                    type: "error",
                    message: "Unrecognized command: " + data.type
                });

                break;
        }
    });

});

wss.on("close", function(){
    if(connection.name){
        delete users[connection.name];

        if(connection.otherName) {
            console.log("Disconnected,",connection.otherName);
            let conn = users[connection.otherName];
            conn.otherName = null;

            if(conn != null){
                sendTo(conn,{
                    type: "leave"
                });
            }
        }
    }
});

wss.on("listening", () => {
    console.log("Server started...");
});

function sendTo(conn, message) {
    conn.send(JSON.stringify(message));
}           

原文 webRTC-NodeJS建立信令伺服器 - 掘金