使用 JavaScript 和 Nodejs 搭建 webrtc信令服务器(webrtc入门一)

由于 WebRTC 入门学习的信息比较杂乱,我决定创建一个教程。希望它对任何想尝试 WebRTC 的人都有帮助。

虽然 WebRTC 不是一项新技术,但它在不断发展。WebRTC 是 (Web Real-Time Communication) 的缩写,允许 Peers 通过 P2P 发送/接收媒体/数据。

在我们深入有趣的部分之前,我们需要设置一个信令服务器,以便对等方可以进行通信,协议可以是任何东西,但通常最终是 WebSockets。也可以在初始信令完成后使用数据通道,我们将在稍后讨论。

让我们开始创建信令服务器。信令服务器可以是任何语言,但为了简单起见,我将使用 JavaScript 和 Nodejs。由于 WebRTC 不适用于不安全的地址,我们还需要提供自签名证书。(如果你打算将其投入生产,请不要使用自签名。)

要求:

  • 一台电脑(显然)
  • Nodejs

IDE可以是你选择的任何东西。我一般更喜欢Vim,因为我总是在使用终端。那么让我们开始吧!

首先为服务器创建目录并初始化应用程序。

mkdir signal-server && cd signal-server
# Also make a directory for the src files
mkdir src
npm init -y

这将创建 package.json 文件,接下来我们需要安装所需的模块。

npm i ws #WebSocket server
npm i nanoid #Used to create a unique id
npm i express #Used to serve static pages

WebSocket 模块可以是任何东西,但为了简单起见,我决定使用 ws 模块。

接下来我们需要创建一个自签名证书来处理 https 连接。

mkdir ssl && cd ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout cert.key -out cert.pem

接下来我们将为服务器创建代码,在 src 文件夹中创建一个名为“server.js”的新文件。现在在你喜欢的 IDE 中打开它,首先我们导入我们将使用的模块。

const express = require('express');
const { createServer } = require('https');
const { readFileSync } = require('fs');
const { nanoid } = require('nanoid');
const { resolve } = require('path');
const { WebSocketServer, OPEN } = require('ws');

我们将创建两个https服务器,一个用于web socket,另一个用于提供静态页面。

接下来我们创建web socket服务器和服务于静态文件的服务器。

const appServer = createServer({
  cert: readFileSync(resolve(__dirname, './../ssl/cert.pem')),
  key: readFileSync(resolve(__dirname, './../ssl/cert.key'))
}, app).listen(3000);

app.use(express.static(resolve(__dirname, './../public')));

const wsServer = createServer({
  cert: readFileSync(resolve(__dirname, './../ssl/cert.pem')),
  key: readFileSync(resolve(__dirname, './../ssl/cert.key'))
});
const wss = new WebSocketServer({ server: wsServer });

接下来我们监听所有socket连接并处理它们,我们稍后会定义它们的功能。

wss.on('connection', (socket) => {
  console.log('new connection');

  socket.on('message', (data) => {
    console.log('socket::message data=%s', data);

    try {
      const jsonMessage = JSON.parse(data);
      handleJsonMessage(socket, jsonMessage);
    } catch (error) {
      console.error('failed to handle onmessage', error);
    }
  });


  socket.once('close', () => {
    console.log('socket::close');
  });
}); 

上面我们监听任何连接,一旦建立连接,我们监听任何通过的消息并将它们解析为 JSON。

现在我们可以定义函数来处理已解析的 JSON 消息。

const handleJsonMessage = (socket, jsonMessage) => {
  switch (jsonMessage.action) {
    case 'start':
      socket.id = nanoid();
      emitMessage(socket, { action: 'start', id: socket.id }); 
      break;
    default: 
      // Default we will just relay the message to the peer
      if (!jsonMessage.data.remoteId) return;

      const remotePeerSocket = getSocketById(jsonMessage.data.remoteId);

      if (!remotePeerSocket) {
        return console.log('failed to find remote socket with id', jsonMessage.data.remoteId);
      }

      // delete/edit the remoteId depending if the action is offer or not
      if (jsonMessage.action !== 'offer') {
        delete jsonMessage.data.remoteId;
      } else {
        jsonMessage.data.remoteId = socket.id;
      }

      emitMessage(remotePeerSocket, jsonMessage);
  }
};

在这里,我们从解析的 JSON 中获取操作,如果操作是“开始”,我们会为套接字(socket)提供一个唯一的 ID,并将其发送回客户端。任何其他我们得到另一个对等方的套接字,然后将消息中继给他们。如果操作不是“offer”,我们会删除 remote id,因为它不再需要了。如果操作是“提供”,我们将远程 ID“切换”给另一方,以便收到答复。

接下来我们将创建缺少的两个辅助函数。

const emitMessage = (socket, jsonMessage) => {
  if (socket.readyState === OPEN) {
    socket.send(JSON.stringify(jsonMessage));
  }
};

// Helper to get socket via id
const getSocketById = (socketId) =>
  Array.from(wss.clients).find((client => client.id === socketId));

如果 socket 处于打开状态,则 emitMessage 只是将消息发送到 socket。getSocketById 只是根据socket ID 返回一个套接字。(我们用 nanoid 定义的唯一 id)

最后让我们启动 web socket 服务器并开始监听。

wsServer.listen(8888);
console.log('app server listening on port 3000');
console.log('wss server listening on port 8888');

这就是排序的信令服务器。现在让我们看看它是否开始!

node src/server.js

# This should print the following output
app server listening on port 3000
wss server listening on port 8888

如果您得到以上输出,则表示信令服务器已准备就绪!

在下一部分中,我们将讨论获取用户的媒体设备(相机和麦克风)以及我们可以使用的约束。

源代码:https://github.com/ethand91/webrtc-tutorial

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/20938.html

(0)

相关推荐

发表回复

登录后才能评论