前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过WebRTC进行实时通信-建立信令服务交换数据

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

作者头像
音视频_李超
发布2020-04-02 18:42:13
2.2K0
发布2020-04-02 18:42:13
举报

概念

为了建立并维护一个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。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概念
  • 前提条件:安装Node.js
  • 关于 App
  • HTML & JavaScript
  • 建立 Socket.IO并运行在 Node.js上
  • 点滴
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档