Зачем использовать AJAX, когда доступны WebSockets?

203

Я уже некоторое время использую WebSockets, и я решил создать инструмент управления Agile-проектом для своего последнего учебного года в университете, используя сервер Node и WebSockets. Я обнаружил, что использование WebSockets обеспечило увеличение количества запросов в секунду на 624%, которое могло обрабатывать мое приложение.

Однако с момента запуска проекта я прочитал о лазейках в системе безопасности, и некоторые браузеры решили отключить WebSockets по умолчанию.

Это приводит меня к вопросу:

Зачем использовать AJAX, когда кажется, что WebSockets делает такую ​​большую работу по снижению задержки и затрат ресурсов, есть ли что-нибудь, что AJAX делает лучше, чем WebSockets?

разъем
источник
2
Вот список движков, которые поддерживают веб-сокеты. en.wikipedia.org/wiki/…
Данте
Некоторые цифры: blog.arungupta.me/rest-vs-websocket-comparison-benchmarks
Руна Джеппесен

Ответы:

209

WebSockets не предназначен для замены AJAX и даже не является заменой Comet / long-poll (хотя во многих случаях это имеет смысл).

Целью WebSockets является предоставление двунаправленного, дуплексного и долговременного соединения с низкой задержкой между браузером и сервером. WebSockets открывает новые домены приложений для браузерных приложений, которые на самом деле были невозможны с использованием HTTP и AJAX (интерактивные игры, динамические медиапотоки, мосты с существующими сетевыми протоколами и т. Д.).

Тем не менее, между WebSockets и AJAX / Comet существует определенное совпадение. Например, когда браузер хочет получать уведомления о серверных событиях (например, push), методы Comet и WebSockets, безусловно, являются приемлемыми вариантами. Если вашему приложению требуются push-события с низкой задержкой, это будет фактором в пользу WebSockets. С другой стороны, если вам необходимо сосуществовать с существующими инфраструктурами и развернутыми технологиями (OAuth, RESTful API, прокси, балансировщиками нагрузки), то это будет фактором в пользу методов Comet (на данный момент).

Если вам не нужны конкретные преимущества, которые предоставляет WebSockets, то, вероятно, лучше придерживаться существующих методов, таких как AJAX и Comet, поскольку это позволяет вам повторно использовать и интегрировать в огромную существующую экосистему инструментов, технологий, механизмов безопасности базы знаний (т. е. гораздо больше людей в стеке потока знают HTTP / Ajax / Comet, чем WebSockets) и т. д.

С другой стороны, если вы создаете новое приложение, которое не работает должным образом с задержкой и ограничениями соединения HTTP / Ajax / Comet, подумайте об использовании WebSockets.

Кроме того, некоторые ответы указывают на то, что одним из недостатков WebSockets является ограниченная / смешанная поддержка серверов и браузеров. Позвольте мне немного рассказать об этом. Хотя iOS (iPhone, iPad) все еще поддерживает более старый протокол (Hixie), большинство серверов WebSockets поддерживают как Hixie, так и версию HyBi / IETF 6455 . Большинство других платформ (если они еще не имеют встроенной поддержки) могут получить поддержку WebSockets через web-socket-js (полифилл на основе Flash). Это охватывает подавляющее большинство веб-пользователей. Кроме того, если вы используете Node для серверного бэкэнда, рассмотрите возможность использования Socket.IO, который включает в себя web-socket-js в качестве запасного варианта, и даже если он недоступен (или отключен), он вернется к использованию любой техники Comet. доступно для данного браузера.

Обновление : iOS 6 теперь поддерживает текущий стандарт HyBi / IETF 6455.

канак
источник
37
И вот на заре 2014 года WebSockets практически является стандартом (RFC 6455) и только Opera mini его не поддерживает.
Дирк Бестер
4
Правда, Opera Mini не поддерживает его, но еще более смущает отсутствие поддержки браузера Android, что делает его немного более сложным для использования с приложениями на основе веб-браузера (Cordova PhoneGap)
Miles M.
2
@kanaka, если они оба одинаково хорошо работают с большими файлами, то почему бы просто не отправить все через websockets? Зачем беспокоиться о страницах / данных, если все можно отправить через WebSockets? (Предположим, что это уже 2020 год, и все браузеры поддерживают WebSockets)
Pacerier
3
@Pacerier полный ответ будет долгим, но он в основном сводится к тому, что вы пытаетесь повторно реализовать вещи, которые браузер уже делает хорошо (кеширование, безопасность, параллелизм, обработка ошибок и т. Д.). Что касается производительности, хотя скорость передачи больших файлов с нуля была бы одинаковой, у браузеров были годы на тонкую настройку кэширования веб-содержимого (большая часть которого относится к запросам AJAX), поэтому на практике переход от AJAX к WebSockets вряд ли обеспечит выгода для существующего функционала. Но для двунаправленной связи с низкой задержкой это огромная победа.
канака
5
Извините, но для меня это не ответ на вопрос. Это просто говорит о том, что они не предназначены для замены друг друга и что WS не поддерживается полностью (сейчас). Это не отвечает, почему вы бы предпочли AJAX веб-сокету? Давайте возьмем Discord для примера. Discord использует WS для передачи сообщений и событий с сервера клиентам, а также использует HTTP-запросы от клиента к серверу (отправка сообщений, запрос данных и т. Д.). Я пришел к этому вопросу, чтобы получить ответ, почему вы это сделаете. Есть ли какая-то техническая причина, по которой вы бы поставили AJAX выше открытого соединения WS?
Шарлотта Дюнуа
63

Перейдем к декабрю 2017 года, веб-сокеты поддерживаются (практически) каждым браузером, и их использование очень распространено.

Однако это не означает, что Websockets удалось заменить AJAX, по крайней мере, не полностью, тем более что адаптация HTTP / 2 находится на подъеме.

Короткий ответ: AJAX по-прежнему отлично подходит для большинства приложений REST, даже при использовании веб-сокетов. Но бог в деталях, так что ...

AJAX для голосования?

Использование AJAX для опроса (или длинного опроса) прекращается (и оно должно быть), но оно все еще используется по двум причинам (в основном для небольших веб-приложений):

  1. Для многих разработчиков AJAX проще в написании кода, особенно когда речь идет о кодировании и проектировании бэкэнда.

  2. С HTTP / 2 была устранена самая высокая стоимость, связанная с AJAX (установление нового соединения), что позволило AJAX-вызовам быть весьма производительными, особенно для публикации и загрузки данных.

Тем не менее, Websocket push намного превосходит AJAX (не требуется повторная аутентификация или повторная отправка заголовков, нет необходимости в обходах без данных и т. Д.). Это обсуждалось несколько раз.

AJAX для отдыха?

Лучшее использование для AJAX - вызовы REST API. Такое использование упрощает базу кода и предотвращает блокирование соединения Websocket (особенно при загрузке данных среднего размера).

Существует ряд веских причин предпочесть AJAX для вызовов REST API и загрузки данных:

  1. AJAX API был практически разработан для вызовов REST API, и он отлично подходит.

  2. Вызовы REST и загрузки с использованием AJAX значительно легче кодировать как на клиенте, так и на сервере.

  3. По мере увеличения полезной нагрузки соединения Websocket могут блокироваться, если не закодирована логика фрагментации / мультиплексирования сообщений.

    Если загрузка выполняется за один sendвызов Websocket , он может заблокировать поток Websocket до тех пор, пока загрузка не будет завершена. Это снизит производительность, особенно на более медленных клиентах.

Обычный дизайн использует небольшие двунаправленные сообщения, передаваемые через веб-сокеты, тогда как REST и загрузка данных (клиент-сервер) используют простоту использования AJAX для предотвращения блокировки веб-сокета.

Однако в более крупных проектах гибкость, предлагаемая Websockets, и баланс между сложностью кода и управлением ресурсами перевесят баланс в пользу Websockets.

Например, загрузки на основе Websocket могут предлагать возможность возобновления больших загрузок после сброса и восстановления соединения (помните, какой фильм объемом 5 ГБ вы хотели загрузить?).

С помощью кодирования логики фрагментации загрузки легко возобновить прерванную загрузку (сложная часть заключалась в кодировании).

Как насчет HTTP / 2 push?

Я, вероятно, должен добавить, что функция HTTP / 2 push не заменяет (и, вероятно, не может) Websockets.

Это обсуждалось здесь ранее, но достаточно упомянуть, что одно соединение HTTP / 2 обслуживает весь браузер (все вкладки / окна), поэтому данные, передаваемые HTTP / 2, не знают, к какой вкладке / окну оно принадлежит, устранение его возможности заменить способность Websocket передавать данные непосредственно на определенную вкладку / окно браузера.

Хотя Websockets отлично подходят для передачи небольших двунаправленных данных, AJAX по-прежнему обладает рядом преимуществ, особенно если учитывать большие полезные нагрузки (загрузки и т. Д.).

А безопасность?

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

AJAX по своей природе будет иметь преимущество, поскольку его безопасность встроена в код браузера (что иногда сомнительно, но оно все еще там).

С другой стороны, вызовы AJAX более восприимчивы к атакам типа «человек посередине», в то время как проблемы безопасности Websockets обычно являются ошибками в коде приложения, который привел к недостатку безопасности (обычно вы найдете их в логике аутентификации бэкэнда).

Лично я не считаю, что это имеет большое значение, во всяком случае, я думаю, что Websockets немного лучше, особенно когда вы знаете, что делаете.

Мое скромное мнение

ИМХО, я бы использовал Websockets для всего, кроме вызовов REST API. Большие загрузки данных я бы фрагментировал и отправлял через Websockets, когда это возможно.

ИМХО, опрос должен быть вне закона, стоимость сетевого трафика ужасна, а управление Websocket достаточно легко даже для новых разработчиков.

Myst
источник
2
Небольшая грамматическая ошибка: «Если что-нибудь я придумаю ...» - подумал 😀
spottedmahn
2
@ spottedmahn - Спасибо! Я думаю, что так и происходит, я использую свой редактор кода для черновика текста 🙃
Myst
1
Извинения, я отсутствовал, когда истек срок действия щедрости. Плохое планирование с моей стороны. Я назначил еще одну награду, которую я назначу вам по истечении 23 часов.
Дункан Джонс
@ Мист, спасибо за это замечательное объяснение. Что бы вы предпочли для живых уведомлений, таких как fb / stackoverflow? Я разрабатываю веб-сервисы RestFull для своего веб-приложения, но очень смущен тем, что я должен использовать для функции уведомлений? AJAX или WebSockets?
TheCoder
Уведомления @puspen (IMHO) отлично подходят для Websockets. При разработке логики переподключения и автономных очередей уведомлений необходимо принять множество решений, но фактическое уведомление легко кодировать и выполнять с помощью веб-сокетов.
Myst
18

Помимо проблем со старыми браузерами (включая IE9, так как WebSockets будет поддерживаться начиная с IE10), по-прежнему существуют большие проблемы с сетевыми посредниками, которые еще не поддерживают WebSockets, включая прозрачные прокси, обратные прокси-серверы и балансировщики нагрузки. Некоторые операторы мобильной связи полностью блокируют трафик WebSocket (то есть после команды HTTP UPGRADE).

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

Алессандро Алиноне
источник
К счастью, большинство фреймворков WebSocket поддерживают упомянутые запасные варианты, включая использование Flash для сокетов. Socketn.IO и SignalR - достойные фреймворки ... хотя вы действительно ограничены, как вы упомянули из-за прокси и балансировщиков нагрузки. К счастью, и Node.JS, и следующий IIS отлично справляются с этой ролью.
Tracker1
Любопытно: какие носители блокируют WebSocket на порту 80? Какой блок защищен WebSocket (WSS) на порту 443? Последнее подразумевает принудительные, прозрачные веб-прокси MITM ... никогда не видел этого в общедоступных сетях (только в корпоративных), поскольку требует установки новых сертификатов CA в браузерах.
oberstet
Например, в настоящее время Vodafone Italy блокирует WS на порту 80, но разрешает WSS на порту 443. Вы можете довольно легко протестировать любого носителя через нашу домашнюю страницу, к которой вы можете получить доступ как по HTTP, так и по HTTPS. Он пытается WebSockets и возвращается к HTTP, если они заблокированы. Используйте этот URL для отображения виджета посередине, который сообщает о текущем транспорте: lightstreamer.com/?s
Алессандро Алиноне
17

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

Тим Ловелл-Смит
источник
11

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

JLI
источник
8
Лучшая причина в том, что AJAX-запрос - это обычный HTTP-запрос, который означает, что он может извлекать HTTP-ресурсы; WebSockets не может этого сделать.
Дэн Д.
@Dan Что, если, например, файлы изображений отправляются как base64, CSS как текст, JavaScript также как текст и затем добавляются в документ? Это было бы правдоподобно?
Джек,
@DanD. +1, я согласен, я думаю, что я больше подходил к вопросу из контекста быстрой передачи данных, как в примере вопроса, но это определенно правильно.
Jli
@Dan D - иногда вы не хотите, чтобы вся эта чушь перешла черту, такую ​​как куки и заголовки ...
vsync
8
@DanD., HTTP и WebSocket - это два разных протокола. Конечно, мы не можем запрашивать ресурсы HTTP, используя протокол WebSocket, по той же причине, по которой мы не можем запрашивать ресурсы WebSocket, используя протокол HTTP! Это не означает, что клиент не может запрашивать HTML и / или файлы изображений, отправленные по протоколу Websocket.
Pacerier
2

Я не думаю, что мы можем провести четкое сравнение Websockets и HTTP, поскольку они не являются конкурентами и не решают одни и те же проблемы.

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

Вы можете обнаружить, что Websockets работают лучше, когда присутствуют высокие нагрузки, в некоторых случаях HTTP немного быстрее, потому что он может использовать кэширование. Сравнение REST с Websockets похоже на сравнение яблок с апельсинами.

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

Гаурав Ганди
источник
1
вопрос был об AJAX вообще, а не REST в частности. Это правда, что AJAX может использоваться для REST, но он также используется для опроса и длинного опроса. Хотя я согласен с вашим выводом (как вы можете сказать из моего ответа), я думаю, что ваш ответ может отражать это различие (обратите внимание, что Websockets можно использовать и для REST, хотя и не с использованием методов HTTP).
Мист
@ Возможно, я согласен с тобой.
Гаурав Ганди
1

Пример различий между HTTP и Websockets в форме библиотеки размера клиента, которая может обрабатывать конечную точку Websocket, например API-интерфейсы REST, и конечные точки RESTful, такие как Websockets на клиенте. https://github.com/mikedeshazer/sockrest Кроме того, для тех, кто пытается использовать API веб-сокетов на клиенте или наоборот, как они привыкли. Libs / sockrest.js в значительной степени проясняет различия (или, скорее, должен).

Майк Д
источник