×
🏆 Пройди Квест на ДСА 2018
Фото Сервер отвечает! Ajax, Comet, WebSocket

Сервер отвечает! Ajax, Comet, WebSocket

Случаются в жизни огорчения — хотел сделать одно, получилось иное. К примеру, протокол, написанный для навигации между документами, используется как файловый сервер. Или делал ты протокол поверх сети Интернет, а теперь его называют «интернет».
Webnetworknginx
21.05.2015

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

Теперь практически всё реализуется с его поддержкой, чтобы «быть в интырнете».  Не предусмотрены протоколом сеансы — добавляем cookie и т.д. Потом, когда увлекаемся извращёнными извращениями — появляются различные Semantic URL, REST, SEO опять же бьёт по рукам тех, кто увлёкся CSS и превратил HTML в span через div. Всё, чтобы слегка сбить спесь и вернуть в родное русло.

Но есть (на данный момент) уж совсем чужеродная хотелка — как сделать так, чтобы не клиент говорил, что ему надо, а сервер. Суть HTTP — клиент спросил документ — мы его отдали. Всё.

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

Иными словами мы переходим к серверам, которые шлют запросы подключённым клиентам.

Подход, надо сразу сказать, инородный. Значит мы имеем удовольствие насладиться новыми элегантными костылями!

Ajax по timeout

Самым простым способом получать изменения в «документе» — периодически спрашивать сервер «что-то произошло?». Из плюсов: простота. В минусах: куча запросов будут лишними, а ответ с сервера будет не «real time», а по запросу. Когда-то ещё любили ставить meta refresh

Comet

Более изощрённый метод — так называемый «long-polling«. Иными словами, мы делаем вид, что всё также забираем с сервера документ, но ждём, пока этот документ не «сгенерируется» — пока не произойдёт на сервере событие, по которому отправится нам информация. Обычно, клиент в таком состоянии висит минут 5, по прошествии которых сервер говорит, что «ничего не произошло». Ответ получен — переподключаюсь! Либо что-то таки происходит — клиент сразу получает желаемое… и переподключается.

Всё в ту же кучу — chunk response — отвечаем «не целым документом», а его «частями» (streaming). Мы можем не пересоздавать запрос каждый раз — просто каждый ответ сервера будет частью некоего «документа».

К примеру, если мы делаем real-time уведомления для пользователей, то сервер будет слать на клиент «части документа» уведомлений. А клиент сможет их получать сразу, без ожидания.

WebSocket

Даёт всё ровно то, что есть в названии. Это аналог TCP-сокетов (транспортного уровня) такие же каналы данных, по которым можно гонять как бинари, так и UTF-8 строки. Особых ограничений нет — просто после запроса к серверу клиент (браузер) не закрывает соединение. В результате: когда хочешь написать — тогда и пишешь, написали тебе — получай данные. По сути — Интернет внутри HTTP.

Comet vs WebSocket

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

Мнение ребят из гугла:

«Reducing kilobytes of data to 2 bytes…and reducing latency from 150ms to 50ms is far more than marginal. In fact, these two factors alone are enough to make Web Sockets seriously interesting to Google.»

Суть: в комете и запросов больше, сами запросы больше (за счёт тех же хедеров HTTP). Да и отклик ниже.

Небольшой надуманный тест производительности:

  • Случай A — 1000 клиентов получают 1 сообщение в секунду. Сообщение 2 байта.
  • Случай B — 10k клиентов.
  • Случай C — 100k.

По количеству гоняемых данных получается ↑. Это про «накладные расходы» и размер запросов.

Утверждение про время отклика также легко описывается схемкой:

По сложности разработки backend схожи: если у нас был обычный web-сервер, который отдавал странички и отвечал на xhr, то теперь нам нужно чтобы он или иной сервер держал коннекты Comet или WebSocket. Тут, скорее всего подойдёт что-нибудь событийно-ориентированное или с потоками уровня приложения. А ля Mojolicious, Twisted|Tornado|gevent, node.js и т.д. Ибо нужно сервить множество клиентов одновременно, но «единица работы» на коннект мала.

Для frontend напилена куча библиотек, а для WebSocket поддержка прямо «из коробки». При чём Comet реализаций (и подходов) несколько, а для WebSocket есть RFC, по которому работает изкоробочная реализация. Плюс всякие обёртки.

Кто поддерживает WebSoket

IE > 9, FireFox, Chrome, Safari, Opera, iOS Safari, Android Browser > 4.3.

Opera Mini не поддерживает.

По рейтингу can i use на данный момент это 86.49%.

Есть поддержка «из коробки» в nginx (с 1.3.13 19.02.2013). Это позволит использовать один порт несколькими вебсокет-серверами. Более того, можно держать HTTP и WS на одном порту. Можно также ограничивать количество соединений с одного IP и прочие радости.

P.S. Эта заметка писалась впопыхах. Основная цель её — собрать различные графики и убедить «работу» в том, что Comet отмирает, а WebSocket — настоящее и ближайшее будущее. Его и стоит использовать.

Будь первым – оставь комментарий!

Фото Маленькая книга о MongoDB
Предыдущая запись:
Маленькая книга о MongoDB
Фото Добавляем поддержку emoji в Django+MySQL приложение
Следующая запись:
Добавляем поддержку emoji в Django+MySQL приложение

Интересное на «Цифре»

Фото Увеличиваем таймауты uwsgi+nginx (обходим 504 Gateway Time-out)
Увеличиваем таймауты uwsgi+nginx (обходим 504 Gateway Time-out)
Если на вашем веб-сервере есть запросы, которые выполняются дольше 60 секунд, вы что-то делаете не так. Даже секунда на запрос — это ужасно долго, а 60 — те, что по умолчанию в nginx — просто ужас. Однако, есть ряд случаев, когда это необходимо/допустимо.
Как добавить HTTPS в nginx на Ubuntu Server (16.04 и выше)
Наличие HTTPS на веб-сайте долгое время считалось роскошью. Тому много причин: особо за безопасность владельцы блогов и «визиток» не парились, а сам сертификат стоил денег (что-то в районе $100 в год).
Фото Команда sudo возвращает ошибку «unable to resolve host»
Команда sudo возвращает ошибку «unable to resolve host»
Это ошибка возникает, когда Linux не может определить хост, на котором он работает. Решение проблемы — добавить хост компьютера в DNS записи. Самый простой путь — добавить строчку в /etc/hosts.
Как очистить кеш DNS записей в Linux
Сколько обновляются DNS записи По-разному. Можно сразу прописать в /etc/hosts — будет сразу.