История WebRTC

Если вы играли в какую-либо веб-игру или общались в онлайн-чате, скорее всего, вы использовали приложение, использующее WebRTC.

WebRTC - это протокол связи в реальном времени, появившийся еще в 2011 году. Google, Mozilla, Opera и даже Ericsson внесли свой вклад в преобразование WebRTC в то, чем он является сейчас: открытый стандарт для дуплексного видео, аудио и видео без плагинов. передача данных.

Другими словами, WebRTC - это причина, по которой вы можете загрузить расширение случайного чата для Chrome или Firefox и начать звонок по видеоконференции в формате Full HD за считанные секунды без дополнительных плагинов или программного обеспечения. Более того, этот протокол позволяет использовать другие типы метаданных и одноранговую связь.

Предыдущие реализации WebRTC, включая Skype, Facebook (построенный на Skype) и Google Hangouts (плагин Google Talk), требовали наличия проприетарных плагинов или собственных приложений. По очевидным причинам эти реализации вышли из моды в пользу API и протоколов, соответствующих открытым, бесплатным и стандартизированным руководящим принципам WebRTC. Эти API теперь встраиваются в современные браузеры и работают более эффективно, чем существующие проприетарные технологии.

Смешанные сигналы WebRTC

API WebRTC по-прежнему нуждаются в серверах, чтобы иметь возможность общаться между одноранговыми узлами, поскольку он координирует и обменивается метаданными между клиентами. Это Сигнализация.

В то время как WebRTC предоставляет архитектуру и API для связи, сигнализация является «оператором», который координирует и устанавливает сеанс с соответствующей информацией. Информация о сеансе, связанная с типами мультимедиа, кодеками, настройками сети и безопасностью, - все это примеры метаданных, которыми обмениваются с помощью сигнализации.

Процесс сигнализации WebRTC основан на JSEP: протоколе установления сеанса JavaScript. JSEP - это набор интерфейсов для идентификации сигналов, в частности, для идентификации согласования локальных и удаленных адресов.

Сигнализация используется для обнаружения одноранговых узлов и обмена предварительными условиями для установки мультимедийных соединений, которые остаются на усмотрение приложения. Этот процесс может быть выполнен с использованием шлюза, такого как WebSockets, XMPP (например, AIM / Pidgin), ICE (установление интерактивного подключения) или, что чаще всего, протокол инициирования сеанса (SIP).

В предыдущих поколениях асинхронной связи API JavaScript был ограничен AJAX или XHR - по сути, совсем не асинхронным. По мере того, как функциональность JavaScript выросла, расширился и WebRTC с WebSockets.

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

Socket.IO

Socket.IO - это надежная библиотека для общения в реальном времени, созданная Гильермо Раухом, техническим директором LearnBoost.

Socket.IO также предоставляет API для Node.js, который работает параллельно с API на стороне клиента. Socket.IO упрощает сигнализацию с использованием WebSockets, но, что более важно, он обеспечивает откаты к другим протоколам (опрос AJAX / JSONP, iframe, Flash и т. Д.) В случае, если WebSockets не поддерживаются браузером или сервером, что дает ему широкие возможности. диапазон совместимости браузера.

Еще одно преимущество, которое стоит отметить, заключается в том, что Socket.IO добавляет интервалы между именами комнат, подключение и детали регистрации, а также большую интеграцию с такими библиотеками, как Angular, Vue, React и другими. В качестве наглядного примера использования WebSockets (WebRTC) в действии попробуйте это забавное небольшое развлечение, созданное командой Mozilla.

ПРИМЕЧАНИЕ. Socket.IO не является реализацией WebSocket. Хотя Socket.IO использует WebSocket в качестве транспортного механизма, когда это возможно, он добавляет некоторые метаданные к каждому пакету: тип пакета, пространство имен и идентификатор подтверждения, когда требуется подтверждение сообщения. Вот почему чистый клиент WebSocket не сможет успешно подключиться к серверу Socket.IO, и наоборот.

Учебное пособие по Socket.IO Chat

К счастью, Socket.IO настолько прост в установке и запуске, что к концу этой статьи вы создадите собственное приложение для чата.

Нашей основной целью будет создание приложения для чата, которое должно иметь следующие функциональные возможности:

  • групповой чат с использованием экспресс и Socket.IO
  • позволить пользователю переписываться с другими пользователями (отправка и получение сообщений)
  • транслировать сообщения всем другим подключенным пользователям в комнате
  • отображать статус пользователей (пользователь печатает…)

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

index.html styles.css index.js chat.js

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

Скопировав HTML и CSS, создайте основу своего проекта с помощью npm install express. Затем идет звезда шоу: Socket.IO. Установите его с помощью npm install socket.io или загрузите библиотеку напрямую из Socket.IO и загрузите из нашего HTML. Вы также можете использовать версию с размещением в CDN.

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

После того, как мы сохранили Socket.IO как зависимость, мы можем начать разработку нашего приложения с серверного JavaScript, создав наши переменные, в частности, требующие нашей явной зависимости и тех переменных, которые необходимы для работы нашего сервера, включая возможность передавать наши статические файлы приложения клиенту через порт 4000. Не забудьте разместить все статические файлы (chat.js, HTML / CSS) в папке с именем 'public', как показано ниже в соответствующей app.use(express.static('public')); строке кода

Файл Index.js:

var express = require('express'); // Express app setup var app = express(); //listens for any requests to our port var server = app.listen(4000, function(){ console.log('listening for requests on port 4000,'); }); // Static files app.use(express.static('public'));

Выполнив эти начальные шаги, мы можем настроить клиентский JavaScript. Сделайте это, подключившись к порту 4000, который мы объявили для нашего приложения в соответствующем файле сервера с помощью метода Socket.IO io.connect. Затем мы привязываем переменные message, handle, btn, output и feedback к их соответствующим идентификаторам в DOM.

Клиент Chat.js:

// Make a socket.io connection var socket = io.connect('http://localhost:4000'); // Assign variables to query the DOM var message = document.getElementById('message'), handle = document.getElementById('handle'), btn = document.getElementById('send'), output = document.getElementById('output'), feedback = document.getElementById('feedback'); ...

Метод socket.emit отправляет дескриптор и сообщение без подтверждения. Для получения дополнительной информации о других методах сокетов см. Emit cheatsheet в документации Socket.IO.

Источники событий по нажатию «click» отправят текст сообщения чата и отобразят его в соответствии с дескриптором, который его отправил, в то время как «нажатие клавиши» используется для отображения «пользователь печатает…» в нашем DIV обратной связи. Socket.on запускает функцию обратного вызова с объектом данных и отправляет его всем подключенным сокетам, просматривающим чат, выводя сообщение и любые последующие сообщения в DOM (output.innerHTML).

// Emit events btn.addEventListener('click', function(){ socket.emit('chat', { message: message.value, handle: handle.value }); message.value = ""; }); message.addEventListener('keypress', function(){ socket.emit('typing', handle.value); }) // Listen for events socket.on('chat', function(data){ feedback.innerHTML = ''; output.innerHTML += '<p><strong>' + data.handle + ': </strong>' + data.message + '</p>'; }); socket.on('typing', function(data){ feedback.innerHTML = '<p><em>' + data + ' is typing a message...</em></p>'; });

В нашем Index.js следующий фрагмент закодирован для прослушивания открытого соединения, отправленного из chat.js, и любых событий сообщений, а затем отправляет сообщение обратно на сервер, который, в свою очередь, транслируется всем остальным, подключенным к чат.

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

// Socket connection setup & pass chat data var io = socket(server); io.on('connection', (socket) => { console.log('made socket connection', socket.id); // Handle chat message event socket.on('chat', function(data){ // console.log(data); io.sockets.emit('chat', data); }); // Handle "user is typing" event socket.on('typing', function(data){ socket.broadcast.emit('typing', data); }); });

Наш завершенный файл index.js на стороне сервера должен выглядеть так:

var express = require('express'); var socket = require('socket.io'); // App setup var app = express(); var server = app.listen(4000, function(){ console.log('listening for requests on port 4000,'); }); // Static files app.use(express.static('public')); // Socket setup & pass server var io = socket(server); io.on('connection', (socket) => { console.log('made socket connection', socket.id); // Handle chat event socket.on('chat', function(data){ // console.log(data); io.sockets.emit('chat', data); }); // Handle typing event socket.on('typing', function(data){ socket.broadcast.emit('typing', data); }); });

Готовый файл chat.js должен выглядеть следующим образом:

// Make connection var socket = io.connect('http://localhost:4000'); // Query DOM var message = document.getElementById('message'), handle = document.getElementById('handle'), btn = document.getElementById('send'), output = document.getElementById('output'), feedback = document.getElementById('feedback'); // Emit events btn.addEventListener('click', function(){ socket.emit('chat', { message: message.value, handle: handle.value }); message.value = ""; }); message.addEventListener('keypress', function(){ socket.emit('typing', handle.value); }) // Listen for events socket.on('chat', function(data){ feedback.innerHTML = ''; output.innerHTML += '<p><strong>' + data.handle + ': </strong>' + data.message + '</p>'; }); socket.on('typing', function(data){ feedback.innerHTML = '<p><em>' + data + ' is typing a message...</em></p>'; });

Готовое приложение для чата должно выглядеть примерно так:

Благодаря абстракции от WebRTC, WebSockets (и многие сложные функции, такие как создание именованных комнат и интеллектуальное переподключение) облегчают бесчисленные головные боли, что делает его идеальным выбором для любого приложения реального времени.

Любые инженерные разработки предприятия, приоритезирующие сроки производства, должны учитывать Socket.IO. Хотя вы можете сэкономить несколько килобайт, используя только чистые WebSockets, Socket.IO поддерживает больше браузеров и имеет более широкую функциональность.

По этим причинам многие инди-игры и веб-приложения успешно разрабатывались с помощью Socket.IO, что привело к его распространению в качестве библиотеки выбора при развертывании технологий WebRTC.

Повсеместное распространение Socket.IO за пределами Node.js означает, что существует сильная поддержка сообщества разработчиков и что его можно реализовать с использованием Ruby, C ++ и Python, и это лишь некоторые из них.

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

«WebRTC - это новый фронт в долгой войне за открытую и ничем не перегруженную сеть». Брендан Эйх, изобретатель JavaScript

Первоначально опубликовано на blog.jscrambler.com.