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

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

Если вы хотите получать самую актуальную информацию в режиме реального времени, вы можете постоянно обновлять эту страницу вручную, но это явно не лучшее решение.

Попытки

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

На основе AJAX было построено множество технологий, все они зависели от javascript без создания нового протокола с использованием HTTP (моделирование).

  • Опрос
  • Длинный опрос
  • Потоковое / вечный ответ
  • Множественные подключения

И каждый метод решает проблему, обнаруженную в предыдущем.

Опрос «продолжайте спрашивать»

  • Браузер регулярно отправляет HTTP-запросы и сразу получает ответ.
  • Сервер всегда немедленно отвечает с данными или без них.

НО…

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

Пример

 Web Browser: I'm going to keep this line open in case you have 
 somestuff to send me.
 Web Server: Okay. Check on me.
 Web Browser: You got anything yet?
 Web Server: No.
 Web Browser: You got anything yet?
 Web Server: No
 Web Browser: You got anything yet?
 Web Server: Yep, here it is.

Длинный опрос

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

  • Браузер отправляет первоначальный запрос.
  • Сервер ждет, пока у него не появятся данные для ответа.
  • Браузер получает ответ и сразу создает новый запрос (цикл)
(function poll() {
    setTimeout(function () {
        $.ajax({
           url: 'https://api.example.com/endpoint/',
           success: function (data) {
               //Do something with 'data'
               //..
               
               //Setup the next poll recursivly
               poll();
           },
            datatype: 'json'
        });
    });
})();
  • Каждый запрос / ответ создает и закрывает соединение
  • Когда у вас большой объем сообщений, длинный опрос не обеспечивает каких-либо существенных улучшений производительности по сравнению с традиционным опросом.

Потоковая передача

Решить проблему открытия / закрытия соединения при длительном опросе.

Браузер отправляет полный запрос, но сервер отправляет и поддерживает открытый ответ, который постоянно обновляется и остается открытым неопределенное время (или в течение определенного периода времени).

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

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

Поэтому многие потоковые решения Comet возвращаются к длительному опросу в случае обнаружения буферизирующего прокси-сервера. В качестве альтернативы можно использовать соединения TLS (SSL) для защиты ответа от буферизации, но в этом случае установка и отключение каждого соединения более сильно нагружает доступные серверные ресурсы.

So…

  • Клиент отправляет первоначальный запрос.
  • Сервер ждет, пока у него не появятся данные для ответа.
  • Сервер отвечает потоковыми данными.
  • Связь поддерживается

Но…

  • Есть проблемы с прокси.
  • Полудуплекс (расскажу об этом)

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

Несколько подключений

  • Длительный опрос по двум отдельным HTTP-соединениям, одно для восходящего потока, например, текущих координат uber-клиента, и одно для нисходящего потока, например, для получения текущих координат uber-драйвера.

Но…

  • Для каждого клиента используются два соединения.
  • Нетривиальная координация и управление подключением

Скрытая стоимость упомянутого метода HTTP

  • Рукопожатие TCB при установлении нового соединения (еще хуже в SSL).
  • Заголовки HTTP в каждом сообщении.

«Уменьшение количества килобайт данных до 2 байтов… и уменьшение задержки со 150 мс до 50 мсек - это намного больше, чем предельное значение. Фактически, одних этих двух факторов достаточно, чтобы сделать WebSocket серьезно интересным для Google ».

- Ян Хиксон (Google, руководитель спецификации HTML5)

Режимы подключения

Односторонний

  • Симплексный канал связи отправляет информацию только в одном направлении. Например, радиостанция обычно посылает сигналы аудитории, но никогда не принимает сигналы от них.

Полудуплекс

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

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

Полный дуплекс

  • Относится к передаче данных в двух направлениях в одном соединении.

Независимо от этого дерьма есть способ получше - это веб-узлы HTML5

  • Полный дуплекс
  • Одно длительное соединение
  • Соединение обновлено с HTTP
  • Эффективное использование полосы пропускания и ЦП

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

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

Ответ сервера:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

Как только веб-сокет установлен

  • Обе стороны уведомили, что розетка открыта.
  • Кадры передаются вперед и назад.
  • Любая сторона может отправлять сообщения в любое время.
  • Любая сторона может закрыть розетку.

Важно отметить, что WebSockets преобразует свое HTTP-соединение в соединение WebSocket. Другими словами, соединение WebSocket использует HTTP только для первоначального рукопожатия (для авторизации и аутентификации), после чего TCP-соединение используется для отправки данных по собственному протоколу.

WebSocket поддерживается не всеми браузерами, поскольку они периодически выпускаются, а socket.io работает как координатор между упомянутыми методами (длительный опрос, потоковая передача и т. Д.) На основе совместимости браузера.

Некоторые фотографии взяты с сайта https://blog.stanko.io/do-you-really-need-websockets-343aed40aa9b