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

Наш стек

  1. Node.js
  2. Express.js
  3. Машинопись
  4. Socket.io

Почему именно Node.js?

Это отличный вопрос. Обычно API REST написаны в модели клиент / сервер, в которой клиент будет требовать определенные ресурсы от сервера и получать эти ресурсы в ответ. Эта архитектура распространена в традиционных веб-приложениях. Сервер реагирует, когда клиент делает запрос, а затем закрывает соединение сразу после каждого ответа. Однако в 2009 году Райан Даль представил новый подход к серверной среде выполнения, написанной на JavaScript. Он позволяет обрабатывать входящие и исходящие запросы на веб-сервер (ввод-вывод) одновременно и асинхронно с использованием концепции, называемой неблокирующим или асинхронным вводом-выводом. Первоначальная идея заключалась в создании веб-сайтов с возможностью push-уведомлений в реальном времени. Так родился Node.js.

В отличие от предыдущей модели клиент / сервер, появилась возможность разрабатывать сайты с двусторонним подключением и бесплатным обменом данными. В основном это связано с WebSockets, которые позволяют открывать интерактивный сеанс связи между браузером пользователя и сервером. Запросы к серверу затем обрабатываются как цикл (точнее, цикл событий), что делает Node.js средой выполнения JavaScript, которая использует «неблокирующий» подход к обслуживанию запросов и, таким образом, обеспечивает низкую задержку и высокую пропускную способность. по пути.

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

Вкратце, Node.js создан для масштабируемых приложений в реальном времени. Я предоставлю ссылки на дополнительные материалы, которые дадут вам дополнительную информацию о том, почему Nodejs идеально подходит для приложений реального времени.

Настройка проекта

Для начала нам нужно сначала установить необходимые пакеты с помощью NPM.

npm init
npm install typescript express ts-node

Теперь давайте настроим элементарный файл tsconfig.json:

tsconfig.json

Теперь, чтобы запустить наш проект, давайте добавим новый скрипт в наш `package.json`.

Теперь мы собираемся создать файл server.ts в каталоге src.

Теперь запустите файл с помощью следующей команды в своем терминале

npm run dev

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

npm i nodemon ts-node @types/node --save

Теперь нам не нужно каждый раз беспокоиться о перезапуске сервера.

Добавляем Socket.io для вкусностей в реальном времени !!!

хорошо, теперь мы готовы добавить socket.io в наше приложение. Сначала давайте установим узел узла.

npm i socket.io --save

и теперь мы меняем наш файл server.js следующим образом

Вот где действительно сияет машинопись. Мы реструктурировали наш код в более объектно-ориентированной манере. Поскольку наше приложение продолжает расти, становится важным поддерживать удобочитаемость. Очень легко следовать и устанавливать шаблоны проектирования с помощью машинописного текста при разработке хорошо масштабируемого кода с низким уровнем дефектов.

Далее мы собираемся создать сервер с использованием http. Итак, мы добавляем следующий код в наш файл chat-server.ts

мы добавили разделы, отмеченные как новые.

Далее мы хотели бы добавить статическую html-страницу. Позже мы можем изменить этот html с помощью одностраничного приложения. Однако пока давайте добавим статический index.html. Для этого мы сначала создаем папку с именем views в нашем каталоге src. У вас должна быть структура каталогов, подобная следующей.

Мы также создали папку маршрутов и файл routes.ts для наших маршрутов. Теперь займемся реструктуризацией кода.

routes.ts

Теперь в нашем файле server.ts у нас будет экземпляр класса маршрута, который будет обрабатывать маршрутизацию к представлениям.

server.ts

Теперь давайте внесем еще несколько изменений в наш файл routes.ts для обслуживания статического контента.

Выше наш файл index.html. Теперь в браузере мы должны увидеть сообщение hello world. Затем мы собираемся добавить JavaScript на стороне клиента на нашу страницу index.html. Для этого нам нужно сообщить express, что мы обслуживаем javascript на стороне клиента. В наш файл chat-server.ts добавляем следующую строку.

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

загрузите клиентский код socket.io и вставьте его в файл socket.js; вы можете получить любой из них с cdnjs.

Https://cdnjs.com/libraries/socket.io

теперь давайте добавим socket.io на сервер, добавив модуль npm

npm i socket-io - сохранить

Инициализируем наш сервер сокетом. для этого внесем следующие изменения в наш файл chat-server.ts

Теперь мы модифицируем метод listen () в нашем файле chat-server.ts. Мы собираемся транслировать наш собственный socket.id всем пользователям, кроме отправителя.

Теперь мы собираемся обновить наш html-файл и добавить код на стороне клиента.

очень простые изменения добавили некоторые элементы в наш файл. Теперь давайте добавим код в файл javascript на стороне клиента index.js.

index.js

Мы прослушиваем событие add-user, которое транслируется сервером. На стороне клиента мы просто извлекаем данные и показываем их на странице.

Теперь, если вы откроете 2 отдельные вкладки, вы увидите, что это указывает на то, что подключен другой пользователь. Это говорит нам о том, что наши розетки работают правильно и мы подключены. Вы также можете заметить, что когда вы покидаете страницу, socket.id не удаляется со страницы. Итак, давайте создадим еще один метод на стороне сервера, который будет транслировать событие, когда пользователь отключается, а на стороне клиента мы будем прослушивать это событие и соответственно изменять представление.

мы добавили приватную переменную, которая будет содержать все идентификаторы сокетов.

Теперь давайте создадим этот метод createOffer (). Этот метод запускается, когда мы нажимаем на один из идентификаторов сокета на стороне клиента. Итак, давайте сейчас создадим этот метод.

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

Https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/

Итак, внутри функции мы создаем новый запрос однорангового соединения, затем мы используем socket.io для отправки события на канал сервера. Я также сделал метод ошибки для обработки любых ошибок.

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

Теперь давайте добавим слушателя предложения на стороне клиента.

В нашем одноранговом соединении мы устанавливаем описание удаленного сокета, а затем генерируем другое событие сокета, называемое make-answer, и отправляем пакет данных через веб-сокеты. И, наконец, на стороне сервера мы добавляем еще одного слушателя make-answer, а затем отправляем полученный ответ клиенту.

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

Теперь перейдите на 2 разные вкладки браузера. Как только вы увидите идентификатор другого человека, нажмите на него, и вы двое будете подключены для видео / аудио разговора.

Код для всего этого раздела можно найти ниже.