Как создать видеочат с WebRTC, используя PeerJS и Node.js

WebRTC приносит много преимуществ пользователю и разработчику, которые в прошлом были менее доступны для создания инструментов общения и совместной работы в Интернете. Например, он предлагает множество способов подключения, с общим элементом чатов и видео. Для создания голосовых или видео соединений в режиме реального времени PeerJS является одной из самых замечательных библиотек, которая позволяет вам реализовать такую ​​функцию в вашем веб-приложении, не испытывая (слишком много) головной боли. PeerJS оборачивает реализацию браузера WebRTC, чтобы обеспечить полный, настраиваемый и простой в использовании API-интерфейс для однорангового соединения. Оборудованный только идентификатором, одноранговый узел может легко создать P2P-соединение для передачи данных или медиа-потока с удаленным одноранговым узлом.

В этой статье вы узнаете, как реализовать видеочат на вашем собственном сервере PeerJS с Node.js.

Прежде чем продолжить

Вам нужно набраться терпения, так как при первой попытке это может не сработать, как ожидается, если вы не все настроите правильно. Так что будьте настойчивы, внимательно прочитайте все инструкции, и вы можете добиться успеха с первого раза.

Если вы считаете, что этот урок очень длинный, мы рекомендуем вам клонировать официальный пример в этом хранилище на Github он содержит весь пример кода, который вы найдете в этой статье, но без объяснения причин. Полезно проверить это самостоятельно.

Содержание руководства

Этот учебник будет расширенным, так что здесь в качестве краткого введения ко всем шагам, которые вы должны будете выполнить:

  1. Получите несколько подписанных сертификатов SSL для тестирования.
  2. Создать структуру демо-проекта
  3. Создайте безопасный локальный сервер с Express для обслуживания наших файлов HTML, CSS и JS.
  4. Создайте безопасный сервер PeerJS, который обрабатывает обмен информацией.
  5. Напишите код для обработки видеочата.
    • Понять, как работает PeerJS.
    • Создать разметку, чтобы создать пример чата.
  6. Разрешить входящие соединения для Node.js и обновить клиентский хост (только при локальном тестировании)
  7. Запустите серверы и протестируйте

1. Создайте или получите сертификат SSL

Чтобы работать в производственном или локальном тестировании, вам нужно будет обработать ваш проект с использованием SSL-сертификата, в противном случае некоторые вещи в браузере могут потерпеть неудачу из-за пользовательских разрешений. Этот шаг полностью зависит от вас, поэтому в соответствии с вашей операционной системой вы можете найти другой учебник о том, как создавать свои собственные самозаверяющие сертификаты SSL. В этой статье показано, как создать самозаверяющий сертификат с помощью openssl в Windows.

Кроме того, вы можете скачать самоподписанные сертификаты из репозитория примеров в Github здесь и использовать их в своей собственной реализации.

2. Структура демонстрационного проекта

Чтобы создать базовый видеочат, нам понадобится базовая структура HTML-проекта и JavaScript:

Заметка

Все файлы (кроме сертификатов и peer.min.js) должен быть пустым, так как мы скажем вам, что писать внутри каждого файла позже.

YourProjectFolder
├───certificates
├── cert.pem
└── key.pem
├───public
├── index.html
├── website-server.js
├── source
│   └── js
|       ├── peer.min.js
│       └── scripts.js
└── package.json
├───server
├── peer-server.js
└── package.json

Вам понадобится 3 папки внутри тестовой папки, а именно сертификаты, общедоступная и серверная. В файле сертификатов вам нужно будет сохранить необходимые файлы, чтобы сервер работал в HTTPS (см. Шаг 1). В общедоступной папке вы найдете индексный файл, который позволяет пользователю общаться в чате и выполнять видеозвонки с кем-то еще, кроме скриптов внутри исходного кода, есть исходный код peer.js для клиентской стороны и scripts.js, который будет записан на шаге 5.

Помните, что структура не обязательно должна быть одинаковой, это всего лишь пример, однако пути к файлам в коде будут следовать этому шаблону, поэтому, если вы измените структуру, помните об изменении ее и в своем коде.

3. Настройка теста локального сервера

В нашем примере мы сделаем доступным простой HTML-файл (index.html) в https: // локальный: 8443 . Для создания нашего сервера мы будем использовать экспресс-модуль, поэтому откройте терминал, переключитесь на project/public добавьте в каталог и измените файл package.json, по крайней мере, со следующими данными, обратите внимание, что вы можете изменить имя вашего проекта в версии, главное, что вам нужно создать действительный файл:

{
"name": "peerjs-videochat-application-client",
"version": "1.0.0"
}

Однажды package.json файл действителен, приступите к установке модуля Express, выполнив:

npm install express

После установки этого модуля вы сможете легко настроить локальный сервер. Теперь перейдите в общую папку проекта и измените файл website-server.js следующим кодом:

Заметка

Серверы используют файлы сертификатов, упомянутые на первом шаге, поэтому, если вы решили изменить структуру вашего примера проекта, обязательно измените путь и к файлам сертификатов.

// project/public/website-server.js
/**
* This script starts a https server accessible at https://localhost:8443
* to test the chat
*
* @author Carlos Delgado (Our Code World)
*/
var fs     = require('fs');
var http   = require('http');
var https  = require('https');
var path   = require("path");
var os     = require('os');
var ifaces = os.networkInterfaces();
// Public Self-Signed Certificates for HTTPS connection
var privateKey  = fs.readFileSync('./../certificates/key.pem', 'utf8');
var certificate = fs.readFileSync('./../certificates/cert.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
/**
*  Show in the console the URL access for other devices in the network
*/
Object.keys(ifaces).forEach(function (ifname) {
var alias = 0;
ifaces[ifname].forEach(function (iface) {
if ('IPv4' !== iface.family || iface.internal !== false) {
// skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
return;
}
console.log("");
console.log("Welcome to the Chat Sandbox");
console.log("");
console.log("Test the chat interface from this device at : ", "https://localhost:8443");
console.log("");
console.log("And access the chat sandbox from another device through LAN using any of the IPS:");
console.log("Important: Node.js needs to accept inbound connections through the Host Firewall");
console.log("");
if (alias >= 1) {
console.log("Multiple ipv4 addreses were found ... ");
// this single interface has multiple ipv4 addresses
console.log(ifname + ':' + alias, "https://"+ iface.address + ":8443");
} else {
// this interface has only one ipv4 adress
console.log(ifname, "https://"+ iface.address + ":8443");
}
++alias;
});
});
// Allow access from all the devices of the network (as long as connections are allowed by the firewall)
var LANAccess = "0.0.0.0";
// For http
httpServer.listen(8080, LANAccess);
// For https
httpsServer.listen(8443, LANAccess);
// Serve the index.html file as content of the / route
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname+'/index.html'));
});
// Expose the js resources as "resources"
app.use('/resources', express.static('./source'));

Этот код устанавливает базовый сервер Express, доступ к которому, как уже упоминалось, можно получить по адресу localhost через порт 8443 (https) в браузере при выполнении. Кроме того, в нем будет указан (после выполнения в консоли) адрес, по которому к нему можно получить доступ с других устройств в локальной сети (см. Шаг 6), или же вы можете удалить его, если развертываете его на производственном сервере.

Сохраните изменения в файле и перейдите к следующему шагу.

4. Настройка сервера PeerJS

PeerServer помогает посредникам подключаться между клиентами PeerJS, а данные не передаются через сервер. Чтобы установить серверный модуль PeerJS, откройте файл package.json, созданный по адресу project/server и добавьте как минимум необходимые параметры для создания корректного файла:

{
"name": "peerjs-videochat-application-server",
"version": "1.0.0"
}

После создания в том же каталоге выполните следующую команду для установки сервера.

npm install peer

Приступить к изменению peer-server.js файл внутри папки сервера (project/server) вашего проекта со следующим содержанием:

// project/server/peer-server.js
var fs = require('fs');
var PeerServer = require('peer').PeerServer;
var server = PeerServer({
port: 9000,
path: '/peerjs',
ssl: {
key: fs.readFileSync('./../certificates/key.pem', 'utf8'),
cert: fs.readFileSync('./../certificates/cert.pem', 'utf8')
}
});

Как вы можете видеть, конфигурация серверной части для PeerJS очень проста, и вам не нужно больше ничего делать на стороне сервера. Вы можете добавить слушателей некоторых событий, однако это не требуется, поскольку Peer Server будет обрабатывать всю необходимую логику автоматически. Этот сервер будет работать на вашем сервере в порту 9000 при запуске.

5. Настройте код на стороне клиента

Клиентская сторона может быть очень простой. Представьте, что это еще одна скучная веб-страница, но она делает что-то потрясающее. Стили, которые вы предоставляете своему проекту, зависят от вас, например, мы используем среду начальной загрузки, чтобы создать хороший макет, используя Церулеанская Тема от Bootswatch.

Разметка (project/public/index.html), который мы будем использовать для нашего примера, выглядит так:


Video Chat with PeerJS
You
Videochat Example
Share the following ID with the pal that wants to talk with you

Connection Form Username Peer ID (id of your pal) An user is already connected to your session. Just provide a name to connect ! Connect to Peer Live chat Call Send Message

Важным в структуре разметки является то, что вы следуете указанным идентификаторам для создания следующего JavaScript. Обратите внимание, что первый тег видео (тот, который будет отображать ваше собственное видео) должен иметь атрибут muted равным true, иначе вы услышите себя, как только начнется передача. Также необходимо включить клиентскую версию Peer.js, этот файл можно получить из официального репозитория здесь или из любого бесплатного CDN. Дело в том, что peer.min.js файл должен быть расположен в project/public/js,

Теперь для project/public/js/scripts.js файл, мы напишем код, который обрабатывает, поэтому начнем с написания прослушивателя событий DOMContentLoaded:

// When the DOM is ready
document.addEventListener("DOMContentLoaded", function(event) {
// All the code of scripts.js here ...
}, false);

Весь код, который мы сейчас объясним, нам понадобится внутри предыдущего обратного вызова. Первое, что вам нужно сделать, это решить, как будет выполняться инициализация на стороне клиента PeerJS, и создать некоторые глобальные переменные (только для scripts.js файл):

var peer_id;
var username;
var conn;
/**
* Important: the host needs to be changed according to your requirements.
* e.g if you want to access the Peer server from another device, the
* host would be the IP of your host namely 192.xxx.xxx.xx instead
* of localhost.
*
* The iceServers on this example are public and can be used for your project.
*/
var peer = new Peer({
host: "localhost",
port: 9000,
path: '/peerjs',
debug: 3,
config: {
'iceServers': [
{ url: 'stun:stun1.l.google.com:19302' },
{
url: 'turn:numb.viagenie.ca',
credential: 'muazkh',
username: '[email protected]'
}
]
}
});

На этом этапе важную роль играет знание WebRTC, поэтому, если вы ничего не знаете об этом, мы рекомендуем вам Узнайте больше о ледовых серверах в этой хорошо написанной статье HTML5 Rocks здесь. В этом примере используются бесплатные серверы Ice, чтобы они работали, однако они могут не работать или быть активными вечно, поэтому в случае ведения бизнеса рекомендуется покупать и владеть собственными серверами STUN или TURN. Таким образом, у вас будет вся инфраструктура, необходимая для развертывания приложений WebRTC промышленного уровня.

С другой стороны, мы используем localhost в качестве хоста, которого обычно может быть достаточно для производства, чтобы оно работало. Если вы тестируете, вы знаете, что вы не можете использовать один и тот же компьютер для тестирования видеочата, потому что два браузера не могут одновременно иметь доступ к камере, поэтому вы, вероятно, выставите Локальный сервер в локальной сети (объяснение в следующем шаге), изменив хост на IP вашего компьютера.

Теперь добавьте несколько слушателей событий к одноранговому узлу, которые позволят вам выполнить некоторые действия, когда наиболее важные события однорангового узла происходят как видеовызов и т. Д.

// Once the initialization succeeds:
// Show the ID that allows other user to connect to your session.
peer.on('open', function () {
document.getElementById("peer-id-label").innerHTML = peer.id;
});
// When someone connects to your session:
//
// 1. Hide the peer_id field of the connection form and set automatically its value
// as the peer of the user that requested the connection.
// 2. Update global variables with received values
peer.on('connection', function (connection) {
conn = connection;
peer_id = connection.peer;
// Use the handleMessage to callback when a message comes in
conn.on('data', handleMessage);
// Hide peer_id field and set the incoming peer id as value
document.getElementById("peer_id").className += " hidden";
document.getElementById("peer_id").value = peer_id;
document.getElementById("connected_peer").innerHTML = connection.metadata.username;
});
peer.on('error', function(err){
alert("An error ocurred with peer: " + err);
console.error(err);
});
/**
* Handle the on receive call event
*/
peer.on('call', function (call) {
var acceptsCall = confirm("Videocall incoming, do you want to accept it ?");
if(acceptsCall){
// Answer the call with your own video/audio stream
call.answer(window.localStream);
// Receive data
call.on('stream', function (stream) {
// Store a global reference of the other user stream
window.peer_stream = stream;
// Display the stream of the other user in the peer-camera video element !
onReceiveStream(stream, 'peer-camera');
});
// Handle when the call finishes
call.on('close', function(){
alert("The videocall has finished");
});
// use call.close() to finish a call
}else{
console.log("Call denied !");
}
});

Теперь добавьте несколько вспомогательных методов для отображения полученных и отправленных данных в виде списка и для запроса видео / аудио в браузере:

/**
* Starts the request of the camera and microphone
*
* @param {Object} callbacks
*/
function requestLocalVideo(callbacks) {
// Monkeypatch for crossbrowser geusermedia
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// Request audio an video
navigator.getUserMedia({ audio: true, video: true }, callbacks.success , callbacks.error);
}
/**
* Handle the providen stream (video and audio) to the desired video element
*
* @param {*} stream
* @param {*} element_id
*/
function onReceiveStream(stream, element_id) {
// Retrieve the video element according to the desired
var video = document.getElementById(element_id);
// Set the given stream as the video source
video.src = window.URL.createObjectURL(stream);
// Store a global reference of the stream
window.peer_stream = stream;
}
/**
* Appends the received and sent message to the listview
*
* @param {Object} data
*/
function handleMessage(data) {
var orientation = "text-left";
// If the message is yours, set text to right !
if(data.from == username){
orientation = "text-right"
}
var messageHTML =  '';
messageHTML += '

'+ data.from +'

'; messageHTML += '

'+ data.text +'

'; messageHTML += '
'; document.getElementById("messages").innerHTML += messageHTML; }

Далее определите прослушиватели событий, которые реагируют на каждое действие пользовательского интерфейса, как событие входа в систему, начальный вызов и т. Д.

/**
* Handle the send message button
*/
document.getElementById("send-message").addEventListener("click", function(){
// Get the text to send
var text = document.getElementById("message").value;
// Prepare the data to send
var data = {
from: username,
text: text
};
// Send the message with Peer
conn.send(data);
// Handle the message on the UI
handleMessage(data);
document.getElementById("message").value = "";
}, false);
/**
*  Request a videocall the other user
*/
document.getElementById("call").addEventListener("click", function(){
console.log('Calling to ' + peer_id);
console.log(peer);
var call = peer.call(peer_id, window.localStream);
call.on('stream', function (stream) {
window.peer_stream = stream;
onReceiveStream(stream, 'peer-camera');
});
}, false);
/**
* On click the connect button, initialize connection with peer
*/
document.getElementById("connect-to-peer-btn").addEventListener("click", function(){
username = document.getElementById("name").value;
peer_id = document.getElementById("peer_id").value;
if (peer_id) {
conn = peer.connect(peer_id, {
metadata: {
'username': username
}
});
conn.on('data', handleMessage);
}else{
alert("You need to provide a peer to connect with !");
return false;
}
document.getElementById("chat").className = "";
document.getElementById("connection-form").className += " hidden";
}, false);

В качестве последнего шага (и его выполнение не требуется немедленно) вы можете вызвать requestLocalVideo метод для запуска собственного потока (который будет использоваться для отправки другому пользователю):

/**
* Initialize application by requesting your own video to test !
*/
requestLocalVideo({
success: function(stream){
window.localStream = stream;
onReceiveStream(stream, 'my-camera');
},
error: function(err){
alert("Cannot get access to your camera and video !");
console.error(err);
}
});

6. Разрешить подключение inbounds для Node.js (только если работает локально)

Если вы пытаетесь получить доступ к указанному адресу (localhost: 8443), но с IP-адреса вашего компьютера вместо localhost с ваших мобильных устройств (устройство Android) или другого устройства в вашей локальной сети, чтобы выполнить тест видеочата (поскольку вы можете ‘ проверить видеочат на одном компьютере) и Node.js заблокирован каким-то правилом брандмауэра, это не будет (вероятно) просто работать:

Artyom Sandbox Внутренняя ошибка IP LAN

Если вы уверены, что сервер работает на вашем компьютере, проблема может быть вызвана ограничением брандмауэра, и для его работы вам потребуется разрешить все входящие подключения к приложению Node.js на вашем компьютере. Например, в Windows вы можете просто открыть брандмауэр, перейти к правилам для входящих подключений и найти Node.js в списке:

Node.js окна брандмауэра входящие и исходящие соединения

Щелкните правой кнопкой мыши по выбранному элементу Node.js и выберите Свойства из контекстного меню. В этом меню перейдите на вкладку «Общие» и в области «Действие» выберите Разрешить соединение переключатель:

Разрешить входящие соединения Node.js

Это должно сработать немедленно, однако, чтобы быть уверенным, перезапустите терминал, в котором был открыт Node, и запустите его снова.

7. Запуск чата

Если бы все прошло как ожидалось, теперь вы могли бы самостоятельно протестировать видеочат. Все, что вам нужно сделать, это запустить файл сервера каждого каталога (публичного и серверного) с Node и позволить им работать в фоновом режиме.

Откройте новый терминал и переключитесь на project/public каталог и выполните следующую команду:

node website-server.js

Это запустит сервер для вашего сайта для тестирования видеочата. Затем откройте другой терминал, переключитесь на project/server каталог и выполните следующую команду:

node peer-server.js

Этот запустит чат-сервер с Peer. Пусть активен терминал 2 и доступ к https: // локальный: 8443 URL с вашим браузером, и вы увидите шаблон Videochat. В этом примере мы будем использовать 2 пользователей, а именно Mr. Huskee (первый пользователь) и Mr. Doge (второй пользователь):

WebRTC видеочат с PeerJS с использованием Node.js

В этом случае камера Мистер хаски начинается автоматически как определенное поведение, которое может быть очевидно изменено, как вы хотите. В данный момент интерфейс ожидает, что кто-то подключится с помощью идентификатора в середине экрана, это означает, что если вы хотите начать видеочат с кем-то, вам нужно только предоставить идентификатор другому пользователю. Если вы не ждете, чтобы кто-то подключился, но вы хотите подключиться к кому-то, тогда вам нужен идентификатор другого пользователя. С другим компьютером или мобильным устройством в этом примере, Мистер дож хочет начать чат с Мистер хаски, поэтому нам нужно ввести идентификатор мистера Хаски (в этом случае 8n9hrtc80tzhvlb6) в нашей форме и нашем имени:

Мобильное устройство Peer JS Videochat Node.js

однажды Мистер дож имеет основные данные формы и нажимает на Connect to Peer, экран Мистер хаски будет автоматически обновлен и покажет сообщение, что кто-то подключен к сеансу, а именно Мистер дож и ему нужно только указать свое имя пользователя:

Видеочат WebRTC PeerJS Войти

Сейчас Мистер хаски вошел в систему и может общаться с Мистер дож легко, поэтому он не может предоставить Peer ID для соединения с кем-то еще, потому что у него уже есть соединение. В чате в данный момент нет видеочата, а есть только текстовый чат:

Видеочат WebRTC PeerJS Node.js

Поэтому кто-то должен будет нажать на кнопку вызова, что в этом случае будет Мистер дож на мобильном устройстве. затем Мистер хаски получит запрос в браузере, если он хочет начать вызов:

Принять видео звонок Videochat Peerjs Webrtc

В случае принятия видеочат запустится без проблем, и они могут говорить и писать так же, как и с такими приложениями, как Skype:

Видеочат WebRTC PeerJS Node.js

Как уже упоминалось в начале статьи, вы можете найти исходный код этого примера в официальном репозитории на Github здесь.

Ссылка на основную публикацию
Adblock
detector