Веб-сокеты делают Ajax/CORS устаревшим?

Сможет ли веб-сокет при использовании во всех веб-браузерах сделать Ajax устаревшим?

Потому что, если бы я мог использовать веб-сокеты для извлечения данных и обновления данных в режиме реального времени, зачем мне нужен Ajax? Даже если я использую ajax для однократной выборки данных при запуске приложения, я все равно захочу посмотреть, изменились ли эти данные через некоторое время.

И будут ли веб-сокеты возможны в кросс-доменах или только к одному источнику?

4 ответа

Решение

WebSockets не сделает AJAX полностью устаревшим, и WebSockets может сделать междоменный.

AJAX

Механизмы AJAX могут использоваться с простыми веб-серверами. На самом базовом уровне AJAX - это просто способ для веб-страницы сделать HTTP-запрос. WebSockets - это протокол гораздо более низкого уровня, для которого требуется сервер WebSockets (встроенный в веб-сервер, автономный или прокси-сервер от веб-сервера до автономного сервера).

В WebSockets кадрирование и полезная нагрузка определяются приложением. Вы можете отправлять HTML/XML/JSON между клиентом и сервером, но это не обязательно. AJAX - это HTTP. WebSockets имеет дружественное HTTP-рукопожатие, но WebSockets не является HTTP. WebSockets - это двунаправленный протокол, который ближе к необработанным сокетам (намеренно), чем к HTTP. Данные полезной нагрузки WebSockets имеют кодировку UTF-8 в текущей версии стандарта, но, вероятно, они будут изменены / расширены в будущих версиях.

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

Междоменному

Да, WebSockets поддерживает кросс-домены. Начальное рукопожатие для установки соединения передает информацию о политике источника. На странице википедии показан пример типичного рукопожатия: http://en.wikipedia.org/wiki/WebSockets

Я постараюсь разбить это на вопросы:

Сможет ли веб-сокет при использовании во всех веб-браузерах сделать Ajax устаревшим?

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

Потому что, если бы я мог использовать веб-сокеты для извлечения данных и обновления данных в режиме реального времени, зачем мне нужен Ajax?

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

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

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

И будут ли веб-сокеты возможны в кросс-доменах или только к одному источнику?

Вы можете иметь междоменные WebSockets, но вы должны написать свой сервер WS, чтобы принять их. У вас есть доступ к заголовку домена (хоста), который вы затем можете использовать для принятия / отклонения запросов. Это может, однако, быть подделано чем-то простым nc, Для того, чтобы действительно защитить соединение, вам нужно будет аутентифицировать соединение другими способами.

У веб-сокетов есть несколько больших недостатков в плане масштабируемости, которых Ajax избегает. Поскольку ajax отправляет запрос / ответ и закрывает соединение (.. или вскоре после этого), если кто-то остается на веб-странице, он не использует ресурсы сервера при простое. Веб-сокеты предназначены для потоковой передачи данных обратно в браузер, и для этого они связывают ресурсы сервера. Серверы имеют ограничение на количество одновременных соединений, которые они могут поддерживать открытыми одновременно. Не говоря уже о том, что в зависимости от вашей серверной технологии они могут связать поток для обработки сокета. Таким образом, веб-сокеты предъявляют более ресурсоемкие требования к обеим сторонам на соединение. Вы можете легко исчерпать все свои потоки, обслуживающие клиентов, и тогда новые клиенты не смогут войти, если множество пользователей просто сидят на странице. Здесь действительно могут помочь nodejs, vertx, netty, но даже у них есть и верхние пределы.

Также существует проблема состояния нижележащего сокета и написания кода с обеих сторон, который поддерживает диалог с состоянием, который не имеет отношения к стилю ajax, потому что он не имеет состояния. Веб-сокеты требуют, чтобы вы создали протокол низкого уровня, который решается за вас с помощью ajax. Такие вещи, как сердцебиение, закрытие простаивающих соединений, переподключение на ошибки и т. Д., Сейчас жизненно важны. Это то, что вам не нужно было решать при использовании AJAX, потому что он не имел состояния. Состояние очень важно для стабильности вашего приложения и, что более важно, для здоровья вашего сервера. Это не тривиально. До HTTP мы создали множество TCP-протоколов с отслеживанием состояния (FTP, telnet, SSH), а затем произошел HTTP. И никто больше этого не делал, потому что даже с его ограничениями HTTP был на удивление проще и надежнее. Веб-сокеты возвращают хорошие и плохие протоколы с отслеживанием состояния. Вы узнаете достаточно скоро, если вы не получили дозу этого последнего обхода.

Если вам нужна потоковая передача данных в реальном времени, эти дополнительные издержки оправданы, потому что опрос сервера для получения потоковых данных хуже, но если все, что вы делаете, это взаимодействие с пользователем ->request->response->update UI, тогда ajax проще и будет использовать меньше ресурсов, потому что после отправки ответа разговор окончен и дополнительные ресурсы сервера не используются. Так что я думаю, что это компромисс, и архитектор должен решить, какой инструмент соответствует их проблеме. AJAX имеет свое место, и вебсетям есть свое место.

Обновить

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

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

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

Вот где приходят асинхронные однопоточные серверы. В Java мы часто называем этот NIO для неблокирующего ввода-вывода. Это означает, что это другой API для сокетов, где отправка и получение данных не блокируют поток, выполняющий вызов.

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

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

socket.read( function( data ) {
   // data is here! Now you can process it very quickly without waiting!
});

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

NIO, асинхронный ввод-вывод, программа, основанная на событиях, так как все это известно, представляет собой гораздо более сложную конструкцию системы, и я бы не стал предлагать вам написать это, если вы только начинаете. Даже очень старшим программистам очень трудно создавать надежные системы. Поскольку вы асинхронны, вы не можете вызывать API, которые блокируют. Как и чтение данных из БД или отправка сообщений на другие серверы должны выполняться асинхронно. Даже чтение / запись из файловой системы может замедлить работу одного потока и снизить масштабируемость. Когда вы переходите в асинхронный режим, это все время происходит в асинхронном режиме, если вы хотите поддерживать движение одного потока. Вот где это становится сложным, потому что в конечном итоге вы столкнетесь с API, таким как БД, который не будет асинхронным, и вам придется использовать больше потоков на некотором уровне. Так что гибридные подходы распространены даже в асинхронном мире.

Хорошей новостью является то, что есть другие решения, которые уже используют этот API более низкого уровня, который вы можете использовать. NodeJS, Vertx, Netty, Apache Mina, Play Framework, Twisted Python, Stackless Python и т. Д. Может быть какая-то неясная библиотека для C++, но, честно говоря, я бы не стал беспокоиться. Серверная технология не требует очень быстрых языков, потому что она связана с IO больше, чем с CPU. Если вы не умеете работать, используйте Java. Он имеет огромное сообщество кода для извлечения, и его скорость очень близка (а иногда и лучше), чем C++. Если вы просто ненавидите это, используйте Node или Python.

Да, да, это так.:D

Более ранним ответам не хватает воображения. Я не вижу больше причин использовать AJAX, если вам доступны веб-сокеты.

Другие вопросы по тегам