由于 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