美文网首页音视频直播技术FFmpeg程序员
通过WebRTC进行实时通信-建立信令服务交换数据

通过WebRTC进行实时通信-建立信令服务交换数据

作者: 音视频直播技术专家 | 来源:发表于2018-10-18 11:04 被阅读8次

    目录

    我们将学习哪些内容

    在这一步,你将发现如何做:

    • 使用 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

    了解如何使用信令使两个用户建立对等连接。

    相关文章

      网友评论

        本文标题:通过WebRTC进行实时通信-建立信令服务交换数据

        本文链接:https://www.haomeiwen.com/subject/aukjzftx.html