nodejs: Ajax против Socket.IO, плюсы и минусы

Я подумал о том, чтобы избавиться от всех вызовов Ajax на стороне клиента (jQuery) и вместо этого использовать постоянное соединение через сокет (Socket.IO).

Поэтому я бы использовал прослушиватели / эмиттеры событий на стороне клиента и на стороне сервера.

Бывший. событие щелчка запускается пользователем в браузере, эмиттер на стороне клиента подталкивает событие через соединение сокета к серверу. Слушатель на стороне сервера реагирует на входящее событие и отправляет событие «готово» обратно клиенту. Слушатель клиента реагирует на входящее событие исчезновением элемента DIV.

Это вообще имеет смысл? За и против?


person ezmilhouse    schedule 25.08.2011    source источник
comment
Взгляните на это: blog.nodejitsu.com/single-page-apps- with-nodejs   -  person Mohsen    schedule 25.08.2011
comment
Подробный ответ, который я дал на аналогичный вопрос: stackoverflow.com/questions/6806263/   -  person Tauren    schedule 26.08.2011


Ответы (3)


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

$.get('/api', sendData, returnFunction); чище, чем socket.emit('sendApi', sendData); socket.on('receiveApi', returnFunction);

Вот почему dnode и nowjs были созданы поверх socket.io, чтобы упростить управление. По-прежнему управляемый событиями, но без отказа от обратных вызовов.

person generalhenry    schedule 25.08.2011
comment
Спасибо большое, nowjs был именно тем, что я искал, я люблю этот новый мир. Есть проблемы с безопасностью? - person ezmilhouse; 26.08.2011
comment
Есть некоторые незначительные проблемы безопасности с протоколом веб-сокетов (без эксплойтов, но известные слабые места), и они решаются. Если есть все эксплойты, вы можете просто отключить веб-сокеты. - person generalhenry; 26.08.2011
comment
Этот ответ сродни тому, чтобы сказать, что лампочки беспорядочные, потому что, когда вы пытаетесь их зажечь, они образуют углеродные зазоры и, в конечном итоге, ломаются и лопаются, поэтому вы должны придерживаться огня. Ты делаешь это неправильно. событиям в первую очередь не нужны обратные вызовы :) Вы используете правильную технологию (события) и неправильную парадигму (обратные вызовы). События позволяют вам просто звонить (без спины). С событиями вы не делаете запросы, вы делаете объявления. Вы не просите чего-то, вы просто говорите, что произошло. socket.emit ('clickedLogin'). Затем, когда логин работает, Node отправляет socket.emit ('loadApp'). Бум, готово. - person Nick Steele; 29.08.2017
comment
С socket.io он обеспечивает обратный вызов socket.emit('sendApi', sendData, returnFunction) - person andyf; 01.08.2019

В этой ветке много распространенной дезинформации, которая очень неточна.

TL / DR; WebSocket заменяет HTTP для приложений! Он был разработан Google с помощью Microsoft и многих других ведущих компаний. Все браузеры его поддерживают. Никаких минусов.

SocketIO построен на основе протокола WebSocket (RFC 6455). Он был разработан для полной замены AJAX. У него вообще нет проблем с масштабируемостью. Он работает быстрее, чем AJAX, при этом потребляет на порядок меньше ресурсов.

AJAX исполнилось 10 лет, и он построен на основе единственного JavaScript XMLHTTPRequest функция, которая была добавлена, чтобы разрешить обратные вызовы серверам без перезагрузки всей страницы.

Другими словами, AJAX - это протокол документов (HTTP) с единственной функцией JavaScript.

Напротив, WebSocket - это протокол приложения, который был разработан для полной замены HTTP. Когда вы обновляете HTTP-соединение (запрашивая протокол WebSocket), вы включаете двустороннюю полнодуплексную связь с сервером, и никакого подтверждения протокола не требуется. С AJAX вы должны либо включить keep-alive (то же самое, что и SocketIO, только старый протокол), либо форсировать новые HTTP-рукопожатия, которые тормозят сервер, каждый раз, когда вы делаете запрос AJAX.

Сервер SocketIO, работающий поверх Node, может обрабатывать 100 000 одновременных подключений в режиме keep-alive, используя только 4 ГБ оперативной памяти и один процессор, и это ограничение вызвано механизмом сборки мусора V8, а не протоколом. . Вы никогда не добьетесь этого с AJAX, даже в самых смелых мечтах.

Почему SocketIO намного быстрее и потребляет меньше ресурсов

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

Если вы погрузитесь в протокол HTTP и используете фреймворки MVC, вы увидите, что один запрос AJAX фактически передает 700-900 байтов нагрузки протокола только на AJAX на URL-адрес (без какой-либо вашей собственной полезной нагрузки). В отличие от этого, WebSocket использует около 10 байт, или примерно в 70 раз меньше данных, чтобы общаться с сервером.

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

Существует неверная информация о том, что соединение сокет является соединением через порт; Нет. Соединение через сокет - это просто запись в таблице. Потребляется очень мало ресурсов, и один сервер может обеспечить более 1 000 000 соединений WebSocket. Сервер AWS XXL может размещать и поддерживает более 1 000 000 соединений SocketIO.

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

Напротив, WebSocket просто сохраняет запись в таблице для соединения, примерно 40-80 байт. Это буквально все. Опрос вообще не происходит.

WebSocket был разработан для масштабирования.

Что касается беспорядка в SocketIO ... Это совсем не так. AJAX беспорядочный, вам нужно обещание / ответ.

С SocketIO у вас просто есть излучатели и приемники; им даже не нужно знать друг о друге; система обещаний не требуется:

Чтобы запросить список пользователей, вы просто отправляете серверу сообщение ...

socket.emit("giveMeTheUsers");

Когда сервер будет готов, он отправит вам еще одно сообщение. Тада, все готово. Итак, чтобы обработать список пользователей, вы просто говорите, что делать, когда получаете ответ, который ищете ...

socket.on("HereAreTheUsers", showUsers(data) );

Вот и все. Где бардак? Ну нет :) Разделение забот? Сделано для вас. Блокировать клиента, чтобы он знал, что ему нужно подождать? Им не нужно ждать :) Вы можете получить новый список пользователей в любое время ... Сервер может даже воспроизвести любую команду пользовательского интерфейса таким образом ... Клиенты могут подключаться к каждому другое даже без использования сервера с WebRTC ...

Система чата в SocketIO? 10 строк кода. Видеоконференцсвязь в реальном времени? 80 строк кода Да ... Люк ... Присоединяйтесь ко мне. используйте правильный протокол для работы ... Если вы пишете приложение ... используйте протокол приложения.

Я думаю, что проблема и путаница здесь исходит от людей, которые привыкли использовать AJAX и думают, что им нужен весь дополнительный протокол обещаний на клиенте и REST API на задней стороне ... Ну, вы не понимаете т. :) Больше не нужно :)

да, вы правильно прочитали ... REST API больше не нужен, когда вы решите переключиться на WebSocket. REST на самом деле устарел. если вы пишете настольное приложение, общаетесь ли вы с помощью диалога с помощью REST? Нет :) Это довольно глупо.

SocketIO, использование WebSocket делает то же самое для вас ... вы можете начать думать о клиентской стороне как о простом диалоге для вашего приложения. REST вам больше не нужен.

Фактически, если вы попытаетесь использовать REST при использовании WebSocket, это так же глупо, как использование REST в качестве протокола связи для диалогового окна рабочего стола ... в этом нет абсолютно никакого смысла.

Что ты говоришь, Тимми? А как насчет других приложений, которые хотят использовать ваше приложение? Вы должны дать им доступ к REST? Тимми ... WebSocket отсутствует уже 4 года ... Просто попросите их подключиться к вашему приложению с помощью WebSocket и позвольте им запрашивать сообщения, используя тот протокол ... он будет потреблять в 50 раз меньше ресурсов, быть намного быстрее и в 10 раз легче развиваться ... Зачем поддерживать прошлое, когда вы создаете будущее?

Конечно, есть варианты использования REST, но все они предназначены для старых и устаревших систем ... Большинство людей просто еще не знают об этом.

ОБНОВИТЬ:

МНОГО людей недавно спрашивали меня, как они могут начать писать приложение в 2018 году (а теперь уже скоро в 2019 году) с использованием WebSockets, что барьер кажется очень высоким, и когда они начнут играть с Socket.IO, они не знаю, куда еще обратиться и чему научиться.

К счастью, последние 3 года были очень хороши для WebSockets ...

В настоящее время существует 3 основных фреймворка, которые поддерживают ОБЕ REST и WebSocket, и даже протоколы IoT или другие минимальные / быстрые протоколы, такие как ZeroMQ, и вам не о чем беспокоиться; вы просто получаете поддержку прямо из коробки.

Примечание. Хотя Meteor, безусловно, является самым популярным, я опускаю его, потому что, хотя это очень, очень хорошо финансируемый фреймворк WebSocket, любой, кто писал код с Meteor в течение нескольких лет, скажет вам , это внутренний беспорядок и кошмар в масштабе. В некотором роде WordPress похож на PHP, он есть, он популярен, но сделан не очень хорошо. Он не продуман до мелочей и скоро умрет. Извините, ребята, Meteor, но посмотрите эти 3 других проекта по сравнению с Meteor, и вы выбросите Meteor в тот же день :)

Со всеми нижеприведенными фреймворками вы пишете свой сервис один раз и получаете поддержку как REST, так и WebSocket. Более того, это одна строка кода конфигурации для переключения практически между любой серверной базой данных.

Feathers Самый простой в использовании, работает одинаково на передней и внутренней стороне и поддерживает большинство функций. Feathers - это коллекция света. -весные обертки для существующих инструментов, таких как экспресс. Используя потрясающие инструменты, такие как перья-vuex, вы можете создавать неизменяемые сервисы, которые полностью подделывать, поддерживать REST, WebSocket и другие протоколы (с использованием Primus), а также получать бесплатные полные операции CRUD, включая поиск и разбиение на страницы, без единой строчки кода (просто какой-то конфиг). Также отлично работает с сгенерированными данными, такими как json-schema-faker, поэтому вы можете не только полностью имитировать вещи, но и использовать случайные, но достоверные данные. Вы можете подключить приложение для поддержки поиска с опережающим вводом, создания, удаления и редактирования без кода (просто сконфигурируйте). Как некоторые из вас, возможно, знают, правильная сквозная конфигурация кода является самым большим препятствием для самомодификации кода. Feathers делает это правильно и подтолкнет вас к лидирующей позиции в будущем дизайне приложений.

Moleculer Moleculer, к сожалению, на порядок лучше в серверной части, чем Feathers. Хотя перья будут работать и позволят вам масштабироваться до бесконечности, перья просто даже не задумываются о таких вещах, как производственная кластеризация, рабочие консоли серверов, отказоустойчивость, готовые журналы трубопроводов или шлюзы API (пока я создавал производственный шлюз API от Feathers, Moleculer делает это лучше, намного лучше). Moleculer также является самым быстрорастущим как по популярности, так и по новым функциям, чем любой фреймворк WebSocket.

Победный удар с Moleculer заключается в том, что вы можете использовать интерфейс Feathers или ActionHero с серверной частью Moleculer, и, хотя вы потеряете некоторые генераторы, вы получите много качества производства.

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

ActionHero Указан здесь как жизнеспособная альтернатива, но Feathers и Moleculer являются лучшими реализациями. Если что-то в ActionHero вам не нравится, не используйте его; есть два лучших способа, описанных выше, которые дают вам больше и быстрее.

ПРИМЕЧАНИЕ. Шлюзы API - это будущее, и все 3 вышеперечисленных поддерживают их, но Moleculer буквально дает вам это прямо из коробки. Шлюз API позволяет массировать взаимодействие с клиентом, позволяя кэшировать, запоминать, отправлять сообщения клиент-клиент, заносить в черный список, регистрировать, обеспечивать отказоустойчивость и все другие проблемы масштабирования, которые решаются одним компонентом платформы. Соединение вашего API-шлюза с Kubernetes позволит вам масштабироваться до бесконечности с наименьшим количеством возможных проблем. Это лучший метод проектирования для масштабируемых приложений.

Обновление 2021 года:

Индустрия настолько изменилась, что вам даже не нужно обращать внимание на протокол. GraphQL теперь по умолчанию использует WebSockets! Просто посмотрите, как использовать подписки, и готово. Самый быстрый способ справиться с этим - вы сами.

Если вы используете Vue, React или Angular, вам повезло, потому что для вас есть собственная реализация GraphQL! Просто вызовите свои данные с сервера с помощью подписки GraphQL, и этот объект данных будет обновляться и реагировать сам по себе.

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

Да если бы вы думали, WTH?!? когда вы услышали, что вы можете просто подписаться, как с FireBase, на объект сервера, и он обновится за вас. да. Теперь это правда. Просто используйте подписку GraphQL. Он будет использовать WebSockets.

Система чата? 1 строка кода. Видеосистема в реальном времени? 1 строка кода. Видеоигра с 10 МБ данных открытого мира, доступными 1 млн пользователей в режиме реального времени? 1 строка кода. Теперь код - это просто ваш запрос GQL.

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

person Nick Steele    schedule 21.12.2015
comment
Многие упомянутые вами подводные камни, касающиеся ajax, решаются с помощью https://http2.github.io/. - person Kevin B; 21.12.2015
comment
HTTP / 2 поддерживается не всеми браузерами, SocketIO есть. HTTP / 2 по-прежнему является протоколом документов, который передает заголовки. WebSocket предназначен для использования после установления соединения. - person Nick Steele; 21.12.2015
comment
Что касается комментария о том, что socket.io быстрее, чем ajax. Объем данных, переданных на стороне одного сетевого кадра, займет такое же количество времени. Обычно 1 пакет может содержать до 1500 байт. Передача запроса размером 80 или 1400 байт займет точно такое же количество времени. На самом деле, на этом этапе это будет зависеть от задержки в вашей сети. Фактически, cubrid.org/blog Тесты / cubrid-appstools / показывают, что при постоянном соединении ajax был лишь немного медленнее, чем socket.io. - person Atifm; 11.02.2016
comment
Приведенное вами сравнение принадлежит человеку, который не понимает, что предлагает Socket.IO. Они использовали метод AJAX для Socket.IO, иначе он не мог бы быть значительно медленнее, чем AJAX, поскольку, очевидно, открытый сокет не требует рукопожатия :) Кроме того, тестер утверждал, что AJAX быстрее кодирует ... не требуют никаких обещаний. Кроме того, накладные расходы в размере 1400 байтов, которые вы будете сжимать / распаковывать, анализировать и иным образом удерживать в памяти, могут подойти для одного клиента, но как насчет сервера с 10 000 подключений? - person Nick Steele; 12.02.2016
comment
@NickSteele - старый пост, но спасибо за потрясающую и подробную информацию о socket.io. Можете ли вы помочь мне понять, что делает реализация HEARTBEAT в socket.io и как ее использовать? Я работаю над тем, чтобы предложить что-то своим коллегам, и я знаю, что одна вещь, которую они поднимут в качестве потенциальной проблемы, - это «а как насчет потерянных связей»? - person tamak; 21.02.2016
comment
Я думаю, вы имеете в виду в основном поддержку активности, просто подтверждение того, что клиент и сервер работают. Передается всего несколько байтов. В Интернете есть доказательства, которые показывают, что вы можете подключить более 500000 клиентов к одному серверу (с достаточным объемом памяти) с тактовыми сигналами или общим состоянием незанятого соединения. В Socket.IO, когда вы теряете соединение и восстанавливаете его, любые события, предназначенные для клиента или сервера, автоматически повторно отправляются при установке соединения. Socket.IO определенно превосходит XHR / AJAX на всех уровнях; он был разработан, чтобы заменить его. - person Nick Steele; 22.02.2016
comment
Очень интересный ответ, спасибо за это, но я думаю, что нет необходимости звучать как 5-летний бешеный - person Hassek; 23.01.2017
comment
@Hassek Спасибо за комментарий и отметил ... Я постараюсь вести себя так, как будто я достигну половой зрелости в будущем. - person Nick Steele; 23.01.2017
comment
Спасибо за информативный ответ. Знаете ли вы о каких-либо недостатках веб-приложения для сотовых планшетов? У нас есть опрос AJAX каждые 20 секунд, он используется часами и, похоже, не разряжает батарею и не использует слишком много данных. Это также сохраняется при отключении / повторном подключении сотовой сети ATT. Как вы думаете, может ли Socket.IO помочь в этом случае? Знаете ли вы о возможных последствиях для времени автономной работы или проблемах с повторным подключением к сотовому Интернету? Спасибо. - person wayofthefuture; 26.03.2017
comment
@wayofthefuture WebSocket имеет на 2 порядка меньше обработки по сравнению с HTTP для выполнения идентичных задач, то есть без обработки gzip / заголовков / текста, однако, если вы проводите опрос только один раз в 20 секунд, разница, безусловно, будет меньше 0,001% средн. аккумулятор планшета, потому что эта обработка будет составлять менее 0,0000001% циклов вашего процессора. Самым большим преимуществом будет передача данных (ячейка будет использовать 5 Вт для передачи пакетов) - и как веб-сокет, так и HTTP-пакет обычно находятся в пределах MTU (размер на пакет) и поэтому потребляют идентичный поток передачи данных. - person Nick Steele; 28.03.2017
comment
Последняя часть вашего ответа была золотой. Я люблю Тимми. Очень информативно. Молодец. - person kemicofa ghost; 16.08.2017
comment
Замечательный ответ. Это прояснило многие опасения, которые испытывает большинство людей. Ваша страсть к технологиям проявляется в вашем ответе :) - person raja kolluru; 22.08.2017
comment
люблю ответ, что Тимми такой молодой олень! - person decoder7283; 01.05.2019

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

Socket.IO в основном предназначен для двунаправленных соединений в реальном времени между клиентом и сервером, и в некоторых приложениях нет необходимости поддерживать постоянные соединения. С другой стороны, асинхронные соединения Ajax должны проходить этап установки HTTP-соединения и отправлять данные заголовка и все файлы cookie с каждым запросом.

Socket.IO был разработан как сервер с одним процессом и может иметь проблемы с масштабируемостью в зависимости от ресурсов сервера, к которым вы привязаны.

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

Приложения Socket.IO сталкиваются с трудностями при SEO-оптимизации и индексации поисковыми системами.

Socket.IO не является стандартным и не эквивалентным W3C Web Socket API. Он использует текущий Web Socket API, если браузер поддерживает, socket.io, созданный человеком для решения кроссбраузерной совместимости в приложениях реального времени, и он настолько молод, около 1 года Старый. Его кривая обучения, меньшее количество разработчиков и ресурсов сообщества по сравнению с ajax / jquery, долгосрочное обслуживание и меньшая потребность или лучшие варианты в будущем могут быть важны для команд разработчиков, чтобы сделать свой код на основе socket.io или нет.

person Reza Hashemi    schedule 25.08.2011
comment
Здесь есть несколько хороших моментов, кроме двух последних. Проблемы SEO применимы к сайтам на основе Ajax так же, как и к сайтам, использующим веб-сокеты. Socket.io будет использовать реализацию веб-сокета W3C в браузерах там, где это возможно, и только в противном случае будет использовать другие методы. - person roryf; 25.08.2011
comment
одним хорошим моментом является ограниченное количество одновременных подключений, главное в SEO - история - code.google.com/web/ajaxcrawling/docs/getting-started.html - person ezmilhouse; 26.08.2011
comment
@ezmilhouse - что ты имеешь в виду? как это история? - person vsync; 03.08.2015
comment
Это полностью выключено. С Ajax вы запускаете 1 поток на запрос. С помощью WebSocket вы добавляете 1 объект в массив ... Около 80 байт для базового соединения. Это означает, что если у вас есть минимальное приложение, вы можете подключить около 1 миллиона пользователей на одном сервере с примерно 80 МБ данных в одном потоке, то есть все пользователи могут обмениваться сообщениями в одном потоке ... это на много порядков. более эффективный. На Земле нет возможности поддерживать 1 миллион запросов ajax на одном сервере, не говоря уже об одном потоке :) - person Nick Steele; 29.08.2017
comment
Если вы используете движок облачных приложений Google, количество пользователей на сервере не будет проблемой из-за автоматического создания нового экземпляра сервера при использовании ресурсов. - person SwiftNinjaPro; 18.12.2019