Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Приложения реального времени и Polling ,Long Polling , WebSockets, Server-Sent Events SSE, WebRTC

Лекция



Привет, Вы узнаете о том , что такое приложения реального времени, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое приложения реального времени, polling, long polling, websockets server-sent events, sse, webrtc , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend) .

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

  1. Клиент делает HTTP-запрос, запрашивая веб-страницу с сервера.
  2. Сервер рассчитывает ответ
  3. Сервер отправляет ответ клиенту

Поскольку разработчики начали изучать способы реализации большего количества приложений « реального времени ». Протокол HTTP сделал такие варианты использования очень сложными, в результате начали появляться творческие способы преобразования модели HTTP-запрос-ответ в модель, работающую в режиме реального времени.

Polling

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC
Самый простой, но самый не эффективный, метод: клиент раз в несколько секунд опрашивает сервер на наличие событий. Даже если ничего нет, то клиент всеравно делает запрос — а мало ли что придет.
Плюсы:
— Просто
— Данные могут быть пожаты
Минусы:
— Очень много лишних запросов
— События всегда приходят с опозданием
— Серверу приходится хранить события пока клиент не заберет их или пока они не устареют

Long Polling

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC
Улучшенный вариант предыдущего метода. Клиент отправляет запрос на сервер, сервер держит открытым соединение пока не придут какие-нибудь данные или клиент не отключится самостоятельно. Как только данные пришли — отправляется ответ и соединение закрывается и открывается следующее и так далее.
Плюсы по сравнению с Polling:
— Минимальное количество запросов
— Высокая временная точность событий
— Сервер хранит события только на время реконнекта
Минусы по сравнению с Polling:
— Более сложная схема

HTTP -streaming

Следующий вариант для рассмотрения HTTP streaming, где несколько ответов могут быть отправлены на один запрос, как показано на рисунке ниже. Это эффективный механизм, но, к сожалению, не приемлем повсеместно во всех конфигурациях прокси / брандмауэре, что делает его непригодным для повсеместного развертывания .

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

WebSockets


Это бинарный дуплексный протокол, позволяющий клиенту и серверу общаться на равных. Этот протокол можно применять для игр, чатов и всех тех приложений где вам нужны предельно точные события близкие к реальному времени.WebSocket - это протокол связи с компьютером который обеспечивает полнодуплексный каналы связи через одиночное TCP-соединение.

Особенности протокола

  • Он отличается от HTTP, но совместим с HTTP.
  • Находится на уровне 7 в модели OSI и зависит от TCP на уровне 4.
  • Работает через порт 80 и 443 (в случае шифрования TLS) и поддерживает HTTP-прокси и посредников.
  • Для достижения совместимости при подтверждении связи WebSocket используется заголовок Upgrade для обновления протокола до протокола WebSocket.

Плюсы по сравнению с Long Polling:

  • Поднимается одно соединение
  • Предельно высокая временная точность событий
  • Управление сетевыми сбоями контролирует браузер
  • Протокол WebSocket обеспечивает взаимодействие между клиентом и веб-сервером с меньшими накладными расходами, обеспечивая передачу данных в реальном времени с сервера и на сервер.

Основное преимущество серверной части WebSockets заключается в том, что это не HTTP-запрос (после рукопожатия), а правильный протокол связи на основе сообщений. Это позволяет достичь огромных преимуществ в производительности и архитектуре . Например, в node.js вы можете использовать одну и ту же память для разных соединений сокетов, чтобы каждый из них мог получить доступ к общим переменным. Следовательно, вам не нужно использовать базу данных в качестве точки обмена посередине (например, с AJAX или длинным опросом с таким языком, как PHP). Вы можете хранить данные в ОЗУ или даже сразу же повторно публиковать их между сокетами.


Минусы по сравнению с Long Polling:
— HTTP не совместимый протокол, нужен свой сервер, усложняется отладка

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC


Так почему же стоит применять SSE, раз у нас есть такой прекрасный протокол WebSockets?! Во-первых не каждому веб-приложению необходима двусторонняя связь — подойдет и SSE. Во-вторых SSE — HTTP совместимый протокол и вы можете реализовать рассылку событий на любом веб-сервере.

Люди часто обеспокоены безопасностью WebSockets. Реальность такова, что это не имеет большого значения или даже делает WebSockets лучшим вариантом. Во-первых, с AJAX вероятность MITM выше , поскольку каждый запрос представляет собой новое TCP-соединение, проходящее через интернет-инфраструктуру. С WebSockets, когда он подключен, гораздо сложнее перехватить между ними, с дополнительной принудительной маскировкой кадров при потоковой передаче данных от клиента к серверу, а также дополнительным сжатием, которое требует больше усилий для проверки данных. Все современные протоколы поддерживают как HTTP, так и HTTPS (с шифрованием). Помните, что WebSockets обычно имеют совсем другой подход к логике работы в сети , больше похожий на игры в реальном времени, чем у http.

Протокол Server-Sent Events

SSE предложил Ian Hickson более 7 лет назад, но только год назад она стала появляться в браузерах. У нас же есть WebSockets зачем нам еще один какой-то протокол?! Но во всем есть свои плюсы и минусы, давайте посмотрим чем же SSE может быть полезен.

Идея SSE проста — клиент подписывается на события сервера и как только происходит событие — клиент сразу же получает уведомление и некоторые данные, связанные с этим событием. Чтобы понять полезность протокола SSE необходимо сравнить его с привычными методами получения событий, вкратце объясню их суть:

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC
Клиент отправляет запрос на сервер, сервер в ответ отправляет следующий заголовок:

Content-Type: text/event-stream


И не закрывает соединение (на php можно создать бесконечный цикл, как сделать на node.js будет объеснено в примере статьи). Вот и все — SSE работает! Чтобы отправить клиенту какие-то данные сервер просто пишет в сокет строку следующего формата:

data: My message\n\n


Если необходимо отправить несколько строк данных, то формат будет следующим:

data: {\n
data: "msg": "hello world",\n
data: "id": 12345\n
data: }\n\n  


Вот, впринципе, и вся база протокола. Кроме этого сервер может отправлять id сообщения это нужно на случай если соединение было разорвано. Если соединение было сброшено, то клиент при попытке подключения отправит специальный заголовок (Last-Event-ID), чтобы восстановить утраченные события:

id: 12345\n
data: GOOG\n
data: 556\n\n


Время переподключения (retry) в случае ошибок:

retry: 10000\n
data: hello world\n\n


Поле id и retry не обязательны.

На клиенте все будет выглядеть следующим образом:

var source = new EventSource('http://localhost/stream.php');
source.addEventListener('message', function(e) {
  // Пришли какие-то данные
  console.log(e.data);
}, false);

source.addEventListener('open', function(e) {
  // Соединение было открыто
}, false);

source.addEventListener('error', function(e) {
  if (e.eventPhase == EventSource.CLOSED) {
    // Соединение закрыто
  }
}, false);


Все предельно просто. Давайте построим приложение на основе протокола SSE. Как водится, это будет чат.

Multipart XMLHTTPRequest


Еще называют multipart streaming (Поддерживает только Firefox). Очень похожий на SSE протокол.
Его заголовок имеет фомат:

Content-type: multipart/x-mixed-replace;boundary=smthing


А части отсылаются в таком формате:

Content-type: text/html\r\n\r\n
--smthing\n
Message\n
--smthing\n



В клиенте создается обычный XHR, но перед отправкой запроса необходимо поставить флаг req.multipart = true;
Правда похоже на SSE?

Есть еще один протокол, который можно привести к SSE:

XMLHTTPRequest: Interactive


Для использования его необходима поддержка браузером специального readyState с кодом 3 (interactive) — этот статус сообщает о том, что часть данных пришла, но соединение еще не закрыто. Для jQuery есть одноименный плагин, использующий readyState с кодом 3. И как всегда не все браузеры поддерживают readyState с кодом 3.


WebRTC

  • WebRTC - это бесплатный открытый проект, который предоставляет браузерам и мобильным приложениям функции связи в реальном времени (RTC) с помощью простых API.

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

Ключевые различия между WebSockets и WebRTC

Оба WebSockets против WebRTC являются популярным выбором на рынке; давайте обсудим некоторые основные различия между WebSockets и WebRTC

  • WebSocket - это компьютерный коммуникационный протокол, тогда как WebRTC - это бесплатный проект с открытым исходным кодом, который позволяет браузерам и мобильным приложениям поддерживать коммуникационные возможности.
  • В центре внимания WebSockets находятся богатые веб-приложения, а в WebRTC - быстрые и простые одноранговые соединения.
  • Хотя оба WebSockets против WebRTC являются протоколами связи, WebRTC используется для большего количества приложений реального времени по сравнению с WebSockets.
  • Среда для WebSockets - это Java, JMS и C ++, тогда как среда для WebRTC - это Java и HTML.
  • У WebSockets больше проблем с безопасностью по сравнению с WebRTC, где основной задачей безопасности является маршрут, через который осуществляется сетевое взаимодействие.
  • Поскольку это относительно новый, WebRTC доступен только в некоторых браузерах, тогда как WebSockets есть в большем количестве браузеров.
  • С точки зрения масштабируемости WebSockets использует сервер за сеанс, тогда как WebRTC является более одноранговым.
  • WebRTC предназначен для высокопроизводительной, высококачественной передачи видео, аудио и произвольных данных. Об этом говорит сайт https://intellect.icu . Приложениям WebRTC требуется сервис, с помощью которого они могут обмениваться метаданными сети и мультимедиа - процесс, известный как сигнализация. WebSocket, с другой стороны, предназначен для двунаправленной связи между клиентом и сервером. Можно передавать и обмениваться аудио и видео через WebSocket, но API недостаточно надежен, как их аналогичные функции в WebRTC.

WebSockets vs Сравнительная таблица WebRTC

Ниже приведено 7 лучших сравнений между WebSockets и WebRTC

Основа сравнения между WebSockets и WebRTC WebSockets WebRTC
Определение WebSocket - это компьютерный коммуникационный протокол, который обеспечивает каналы связи по одному TCP-соединению. WebRTC - это бесплатный открытый проект, который предоставляет браузерам и мобильным приложениям возможности связи в реальном времени с помощью простых API.
обзор
  • Ключевыми моментами веб-сокетов являются истинный параллелизм и оптимизация производительности, что приводит к более отзывчивым и насыщенным веб-приложениям.
  • Протокол Web Socket определяет полнодуплексную связь с нуля.
  • WebSockets представляют собой эволюцию, поскольку они делают шаг вперед в обеспечении функциональности настольных компьютеров в веб-браузерах.
  • WebRTC позволяет пользователям быстро и легко устанавливать одноранговые соединения с другими веб-браузерами.
  • В WebRTC такие проблемы, как потеря данных, разрыв соединения и обход NAT, встроены в браузер.
  • API WebRTC включает захват медиа, кодирование и декодирование аудио и видео, транспортный уровень и управление сеансами.
Пользы
  1. Социальные каналы
  2. Многопользовательские игры
  3. Совместное редактирование / кодирование
  4. Данные о потоке кликов
  5. Финансовые тикеры
  6. Спортивные обновления
  7. Мультимедийный чат
  8. Приложения на основе местоположения
  9. Онлайн образование
  1. Маркетинг в реальном времени
  2. Реклама в реальном времени
  3. Коммуникации бэк-офиса (CRM, ERP, SCM, FFM)
  4. Управление персоналом
  5. социальная сеть
  6. Службы знакомств
  7. онлайн медицинские консультации
  8. финансовые услуги
  9. наблюдение
  10. многопользовательские игры
  11. прямой эфир
  12. Электронное обучение
Архитектура Архитектура для WebRTC состоит из слоев:

  1. Браузеры
  2. интернет
  3. Сервер или шлюз WebSocket
  4. Служба сообщений
  5. Торговый шлюз, новостная лента, платежная система, хранилище баз данных, логика приложений, веб-сервис, ERP / CRM система и настольное решение.
WebRTC имеет сложную архитектуру. Архитектура WebRTC имеет три уровня.

  1. API для веб-разработчиков
  2. API для производителей браузеров
  3. Переопределяемый API
Окружающая обстановка Java, JMS, C ++ Перед созданием приложений WebRTC важно установить среду кодирования. Во-первых, у нас должен быть текстовый редактор, в котором мы можем редактировать HTML и JavaScript. Еще одно требование - сервер для размещения файлов HTML и JavaScript.
Характеристики
  • WebSockets стандартизированы, что означает, что с этим протоколом возможна связь между веб-серверами и клиентами в режиме реального времени.
  • Он трансформируется в кроссплатформенный стандарт для связи в реальном времени между клиентом и сервером.
  • Стандарт WebSockets позволяет создавать новые виды приложений, особенно для бизнеса, для веб-приложений реального времени.
  • Самым большим преимуществом и особенностью WebSockets является то, что она обеспечивает двустороннюю связь по одному TCP-соединению.
  • Распределенная связь - это соединение с клиентского устройства на другое клиентское устройство без использования серверов.
  • Доступ к камере, микрофону и экрану.
  • Многопартийная конференц-связь на мобильном телефоне
Безопасность Проблемы безопасности для WebSockets включают в себя:

  • Отказ в обслуживании
  • Человек посередине
  • Межсайтовый скриптинг
  • Клиент-серверное маскирование
  • Панель инструментов безопасности
  • Инструменты разработчика браузера

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

Изучив сравнение и различия между WebSockets и WebRTC, мы узнали, что оба WebSockets против WebRTC являются протоколами, обеспечивающими связь. WebSockets обеспечивают двустороннюю связь через единую связь TCP, тогда как WebRTC обеспечивает одноранговую связь в режиме реального времени в браузере и мобильных приложениях. Оба WebSockets против WebRTC имеют Java в качестве основной среды. Хотя API-интерфейсы WebSockets включены с возможностью передачи видеосвязи, они не так надежны, как WebRTC

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

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Служба сообщений для сигнализации должна быть двунаправленной: клиент-сервер и сервер-клиент. В этом случае мы можем использовать WebSocket, который предназначен для полнодуплексного взаимодействия клиент-сервер. Для поддержки пользователей с высокой степенью одновременного использования нашему приложению WebRTC требуются сигнальные серверы, способные выдерживать значительную нагрузку.

В этом случае мы можем выполнить вертикальное масштабирование, добавив несколько серверов сигнализации за балансировщиком нагрузки. Проблема возникает, когда два одноранговых узла собираются позвонить, но подключаются к разным серверам. Итак, как эти два сервера общаются друг с другом? Решение - использовать очередь сообщений, такую ​​как ZeroMQ, Redis и т. Д.

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

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Использование серверов TURN

В некоторых случаях, когда клиенты используют NAT и брандмауэры, невозможно установить одноранговое соединение с помощью STUN. Такая ситуация часто возникает, когда клиент работает в корпоративной сети со строгой политикой подключения. В таком случае единственный способ установить соединение - использовать сервер TURN. Сервер TURN работает как прокси - все данные между одноранговыми узлами (включая аудио, видео и служебные данные) проходят через сервер TURN.

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Сервер TURN должен поддерживать аутентификацию и запрещать анонимный доступ. При использовании службы TURN весь трафик от одного узла к другому проходит через сервер TURN.

Нам также может потребоваться вертикальное масштабирование для серверов TURN, добавив балансировщик нагрузки.

Сочетание лучшего

Мы можем настроить сервер TURN как резервный вариант, когда одноранговое соединение не может быть установлено с помощью STUN. Таким образом мы сможем объединить лучшее из обоих миров.

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Сравнение различных методов коммуникации в сети:

  • AJAX - requestresponse. Создает соединение с сервером, отправляет заголовки запроса с дополнительными данными, получает ответ от сервера и закрывает соединение. Поддерживается во всех основных браузерах.

  • Long poll - requestwaitresponse. Создает соединение с сервером, как это делает AJAX, но поддерживает соединение keep-alive в течение некоторого времени (хотя и ненадолго). Во время подключения открытый клиент может получать данные с сервера. Клиент должен периодически переподключаться после закрытия соединения из-за тайм-аутов или eof данных. На стороне сервера он по-прежнему обрабатывается как HTTP-запрос, такой же, как AJAX, за исключением того, что ответ на запрос произойдет сейчас или когда-нибудь в будущем, что определяется логикой приложения. Long poll - это грязный обходной путь для предотвращения создания соединений для каждого запроса, как это делает AJAX, но длинный опрос был создан, когда WebSockets не существовало. Теперь из-за WebSockets длинные опросы ушли.

  • WebSockets - clientserver. Создайте TCP-соединение с сервером и держите его открытым столько, сколько необходимо. Сервер или клиент могут легко закрыть соединение. Клиент проходит через процесс установления связи, совместимый с HTTP. В случае успеха сервер и клиент могут обмениваться данными в обоих направлениях в любое время. Это эффективно, если приложение требует частого обмена данными обоими способами. В WebSockets есть кадрирование данных, которое включает маскировку для каждого сообщения, отправляемого от клиента к серверу, поэтому данные просто зашифровываются. график поддержки (очень хорошо) | википедия

  • WebRTC - peerpeer. Транспорт для установления связи между клиентами и не зависит от транспорта, поэтому он может использовать UDP, TCP или даже более абстрактные уровни. Обычно это используется для передачи больших объемов данных, таких как потоковое видео / аудио, где надежность является второстепенной, и можно пожертвовать несколькими кадрами или снижением качества в пользу времени отклика и, по крайней мере, некоторой передачи данных. Обе стороны (одноранговые узлы) могут передавать данные друг другу независимо. Хотя его можно использовать полностью независимо от каких-либо централизованных серверов, он по-прежнему требует определенного способа обмена данными о конечных точках, когда в большинстве случаев разработчики по-прежнему используют централизованные серверы для «связывания» одноранговых узлов. Это требуется только для обмена важными данными для установления соединения, после чего централизованный сервер не требуется. WebRTC позволяет осуществлять одноранговую связь.

  • События, отправленные сервером - clientserver. Клиент устанавливает постоянное и долгосрочное соединение с сервером. Только сервер может отправлять данные клиенту. Если клиент хочет отправить данные на сервер, для этого потребуется использование другой технологии / протокола. Этот протокол совместим с HTTP и прост в реализации на большинстве серверных платформ. Это предпочтительный протокол для использования вместо длительного опроса. график поддержки (хорошо, кроме IE) | википедия

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTCПриложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Рис Сравнение различных видов соединенией реального времени и процессорного времени

  • Обновление страницы вручную (контроль) После каждого интервала в 1 секунду страница обновляется. Этот метод не позволяет наблюдать за поведением в реальном времени.
  • Короткий опрос HTTP (интервал 250 мс)
    Короткий опрос постоянно открывает и закрывает HTTP-запросы, ищущие новые обновления через определенный интервал. В идеале интервал соответствует ожидаемым обновлениям.
  • Длинный опрос HTTP.
    Длинный опрос открывает HTTP-запрос и остается открытым до получения обновления. После получения обновления сразу же открывается новый запрос, ожидающий следующего обновления.
  • События, отправленные
    сервером События, отправленные сервером (SSE), основываются на долгоживущем HTTP-соединении, при котором обновления постоянно отправляются клиенту.
  • WebSockets (через WS) Протокол WebSocket обеспечивает постоянную двунаправленную связь между сервером и клиентом. В этом тесте Primus используется для абстрагирования нескольких реализаций протокола. Этот метод использует реализацию WS .
  • WebSockets (через Engine.IO) То же, что и метод WS, на основе реализации Engine.IO .
  • WebSockets (через Faye) То же, что и метод WS, на основе реализации Faye .
  • WebSockets (через SockJS) То же, что и метод WS, на основе реализации SockJS .

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Пример: Чат на Server-Sent Events


Мы будем принимать поток событий по SSE: уход в оффлайн, приход в онлайн, сообщение. Т.к. по SSE нельзя отправлять сообщение, то мы будем отправлять их по HTTP.

Схема работы такая:
— При входе в чат запрашивается имя
— Клиент подключается к серверу чата. Создается поток событий.
— При подключении клиента чат рассылает всем событие: %username% online
— При отключении клиента чат рассылает всем событие: %username% offline
— Клиент может отправлять сообщение по HTTP «POST /message» Cервер принимает это сообщение и рассылает всем клиентам принятое сообщение по SSE

Разберем код клиента. Для того, чтобы у некоторых браузеров не было бесконечной загрузки мы вместо $.ready выполняем setTimeout:

setTimeout(function () { // Ставлю именно таймаут, а не $.ready иначе у вебкитов будет бесконечная загрузка
}, 50);


Запрашиваем имя пользователя:

// Получаем имя из localStorage и запрашиваем новое
var name = (prompt('Name:', window.localStorage ? window.localStorage['name'] || '' : '') || 'anonymous').substr(0, 20);

// Пытаемся сохранить имя
if (window.localStorage) {
    window.localStorage['name'] = name;
}


Создаем EventSource и передаем ему имя пользователя (теперь пользователь онлайн) и слушаем необходимые события:

var eventSrc = new EventSource("/event?name=" + name);

// Слушаем событие EventSource - "message"
eventSrc.addEventListener("message", function(event) {
    var data = JSON.parse(event.data);
    // Отрисовываем пришедшее с сервера сообщение
    renderMessage(data);
}, false);

// Слушаем событие EventSource - "error"
eventSrc.addEventListener("error", function(event) {
    // Сообщаем о проблеме с подключением
    renderMessage({
        isbot: true,
        message: 'connection error',
        name: '@Chat'
    });
}, false);


Не буду рассматривать метод renderMessage и разметку страницы. Весь код клиента можно посмотреть тут: index.html

На стороне сервера у нас будет Node.js. Тут все сложнее, но основная сложность в мультикасте сообщений от одного пользователя ко всем, а не в построении коммуникации по SSE.

Подключаем необходимые модули

var http = require('http'),
    fs = require('fs'),
    qs = require('querystring'),
    parse = require('url').parse;

// Кэшируем статику (index.html мы будет отдавать с помошью Node.js)
var indexFile = fs.readFileSync('index.html'); // Buffer

Роуты


Создаем список роутов Routes, включающий в себя следующие объекты:
1. Статика. Индексная страница, мы просто шлем статику:

    'GET /': function (request, response) {
        // Шлем правильные заголовки
        response.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'});
        response.write(indexFile);
        response.end();
    }


2. Поднятие SSE соедиения:

    'GET /event': function (request, response) {
        var url = parse(request.url, true);
        var name = (url.query.name || 'anonymous').substr(0, 20);
        var clientId = Clients.generateClientId();

        // Шлем спец заголовок для EventSource
        response.writeHead(200, {'Content-Type': 'text/event-stream'});

        // Выставляем больший таймаут на сокет, иначе сокет запроется через 2 минуты
        request.socket.setTimeout(1000 * 60 * 60); // 1 Час

        // Если соединение упало - удаляем этого клиента
        request.on('close', function () {
            Clients.remove(clientId);
        });

        // Добавляем клиента в список
        Clients.add(clientId, response, name);
    }


3. Сообщение от клиента:

    'POST /message': function (request, response) {
        var data = '';
        // Пришел кусочек тела POST
        request.on('data', function (chunk) {
            data += chunk;
        });

        // Все кусочки POST тела собраны
        request.on('end', function () {
            // Парсим тело
            data = qs.parse(data);

            // Рассылаем всем сообщение
            Clients.broadcast(data.message, data.name, false);
            response.writeHead(200);
            response.end();
        });
    }


4. Роут по умолчанию — Страница 404:

    $: function (request, response) {
        response.writeHead(404);
        response.end();
    }

Менеджер клиентов — Clients


При добавлении нового клиента (add) менеджер рассылает все сообщение о том, что клиент пришел:

    add: function (clientId, response, name) {
        this._clients[clientId] = {response: response, name: name || 'anonymous'};
        this.count++;

        // Рассылаем сообщения от имени бота
        this.unicast(clientId, 'Hello, ' + name + '! Online ' + this.count, '@ChatBot', true);
        this.broadcast(name + ' online', '@ChatBot', true);
    }


При удалении закрывает соединение и рассылает всем, что клиент оффлайн:

    remove: function (clientId) {
        // Если клиента нет, то ничего не делаем
        var client = this._clients[clientId];
        if (!client) {
            return;
        }
        // Закрываем соединение
        client.response.end();
        // Удаляем клиента
        delete this._clients[clientId];
        this.count--;
        
        // Сообщаем всем оставшимся, что он вышел
        // Рассылаем сообщения от имени бота
        this.broadcast(client.name + ' offline', '@ChatBot', true);
    }


Для отправки сообщений клиентам используется private метод _send:

    _send: function (clients, message, name, isbot) {
        if (!message || !name) {
            return;
        }
        // Подготавливаем сообщение
        var data = JSON.stringify({
            message: message.substr(0, 1000),
            name: (name || 'anonymous').substr(0, 20),
            isbot: isbot || false
        });

        // Создаем новый буфер, чтобы при большом количестве клиентов
        // Отдача была более быстрой из-за особенностей архитектуры Node.js
        data = new Buffer("data: " + data + "\n\n", 'utf8'); // Формат сообщение SSE

        // Рассылаем всем
        clients.forEach(function (client) {
            client.response.write(data); // Отсылаем буфер
        });
    }


Метод _send используют public методы broadcast и unicast для рассылки сообщения всем и одному клиенту соответственно.

Создаем и включаем сервер

// Создаем сервер
var httpServer = http.createServer(function (request, response) {
    var key = request.method + ' ' + parse(request.url).pathname;

    // Если роута нет, то отдаем по умолчанию Routes.$ - 404
    (Routes[key] || Routes.$)(request, response);
});

// Включаем сервер
httpServer.listen(80);
console.log('Online'); 


Исходный код server.js https://github.com/azproduction/event-source-chat/blob/master/server.js

Наш чат на SSE готов. Запускаем сервер:

$ node server.js


Открываем один из браузеров: Firefox 6, Opera 10.6+, Chrome, WebKit 5+, iOS Safari 4+, Opera Mobile 10+. Переходим на http://localhost/ и чатим!

Заключение


SSE — хорошая технология, которая должна вытеснить Long Poling она проста и не менее эффективна, чем WebSockets. Сейчас SSE поддерживают Opera 10.6+ (Opera 9 поддерживает старый стандарт SSE), Chrome, Safari 5+. Firefox поддерживает Multipart XMLHTTPRequest, для которого можно написать обертку и использовать как интерфейс SSE.
Сравнение методов передачи данных

Приложения реального времени  и Polling ,Long Polling , WebSockets, Server-Sent Events   SSE, WebRTC

Ссылки


1. Онлайн пример SSE чата можно посмотреть вот тут: sse-chat.nodester.com
Это несколько урезанная версия чата из-за особенностей проксирования Nodester (нет сообщения о количестве пользователей онлайн и нет сообщений о выходе из чата, может быть частый реконнект)
2. Исходник примера: github.com/azproduction/event-source-chat

Представленные результаты и исследования подтверждают, что применение искусственного интеллекта в области приложения реального времени имеет потенциал для революции в различных связанных с данной темой сферах. Надеюсь, что теперь ты понял что такое приложения реального времени, polling, long polling, websockets server-sent events, sse, webrtc и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)

создано: 2017-06-11
обновлено: 2024-11-14
128



Рейтиг 9 of 10. count vote: 3
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)

Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)