Сервер отправляет события и Ajax VS Websockets и Ajax - PullRequest
1 голос
/ 07 ноября 2019

Я создаю приложение (Nuxtjs), и у меня возникают проблемы с определением подходящего способа отправки данных в API (expressjs) и получения обновлений в режиме реального времени. Похоже, что я могу создать "bi-di" соединения с обоими протоколами [Server Sent Events (SSE) и Axios или Websocket (WS)].

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

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

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

Веб-сокеты:

  1. Не всем компонентам потребуется WS для получения / публикации информации, поэтому не имеет смысла обновлять базовое http-соединение за дополнительную плату сервера. ,Поэтому потребуется другой метод, отличный от WS (Axios/SSR). Example: Checking to see if a user name exists
  2. Брандмауэры безопасности могут помешать WS для правильной работы
  3. express-ws упрощает сокеты на стороне API
  4. Я полагаю, вы можете иметь более 6 одновременныхсоединения одного пользователя (которые могут быть за и против)

События, отправленные сервером

  1. Похоже, что технология исчезает в пользу WS
  2. Прослушивание событий выглядит так же просто, как прослушивание событий для WS
  3. Нет необходимости обновлять соединение, но придется использовать node-spdy в expressjs API - это также может бытьхорошая реализация для WS из-за мультиплексирования
  4. Немного больше бэкэнд-кода для настройки http2 и генерации SSE s (а также уродливый код - так будут выполняться функции)
  5. Limitedк ограничениям HTTP (6 одновременных подключений), что является проблемой, поскольку пользователи могут легко максимизировать это (т. е. если открыто несколько окон чата)

TLDR

Приложение будет более "кормить", ориентировано на Occasional posting (который может быть обработан Axios). Однако пользователи будут прослушивать несколько «каналов», и ограничения HTTP будут проблемой. Я не знаю, каким будет решение, потому что SSE кажется лучшим вариантом, так как мне не нужно постоянно рукопожатие. Если это рукопожатие действительно несущественно (что из всего, что я прочитал, не соответствует действительности), то WS, вероятно, является лучшей альтернативой. К сожалению, существует слишком много противоречивой информации относительно этих двух.

Мысли?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

SSE, веб-сокеты и обычные HTTP-запросы (через AJAX или Fetch API) - это разные инструменты для разных заданий.

SSE

  • Однонаправленный, от сервера к клиенту.
  • Только текстовые данные. (Все остальное должно быть сериализовано, например, JSON.)
  • Простой API, широко совместимый, автоматическое переподключение, имеет встроенное условие для обнаружения возможных пропущенных событий.

WebСокеты

  • Двунаправленные.
  • Текстовые или двоичные данные.
  • Требуется реализовать собственное значение для отправляемых данных.

Стандартные HTTP-запросы

  • Клиент-сервер или Сервер-клиент, но только одно направление за раз.
  • Текстовые или двоичные данные.
  • Требуется дополнительное усилиедля потоковой передачи ответа от сервера к клиенту в режиме реального времени.
  • Для потоковой передачи от клиента к серверу необходимо, чтобы все данные были известны во время запроса. (Вы не можете создать поток событий, например.)

Как решить:

  • Вы передаете данные, подобные событиям, с сервера на клиент? Используйте SSE. Он специально создан для этого и представляет собой простой способ.
  • Отправляете ли вы данные только в одном направлении, и вам не нужно спонтанно уведомлять клиентов о чем-то? Используйте обычный HTTP-запрос.
  • Нужно ли отправлять двунаправленные данные с установлением долгосрочного соединения? Используйте веб-сокеты.

Из вашего описания может показаться, что SSE или веб-сокеты подойдут для вашего случая использования. Я бы, вероятно, склонялся к SSE, отправляя случайные вызовы API от клиента с обычными HTTP-запросами.

Я не знаю, каким было бы решение, потому что SSE кажется лучшим вариантом, чем я. не надо постоянно рукопожатие. Если это рукопожатие действительно несущественно (что из всего, что я прочитал, не соответствует действительности), то WS, вероятно, является лучшей альтернативой.

Имейте в виду, что вы можете просто настроить свой сервер с помощью HTTP keep-живой, что делает этот вопрос спорным.

0 голосов
/ 07 ноября 2019

Лично я избегаю использования websockets в качестве двусторонней связи между client и server.

Я пытаюсь использовать сокеты для broadcast data from server to users or a single user(socket), чтобы они могли получать обновления в режиме реального времени,но для почтовых запросов от клиента к серверу я склонен использовать axios или что-то подобное, потому что я не хочу передавать конфиденциальные данные (например, ключи доступа и т. д.) от client до server.

Myпоток данных выглядит примерно так:

  1. Пользователь отправляет данные на сервер, используя axios, SSE или любой другой
  2. Сервер Backend делает то, что должен, и уведомляет сокет о том, что событие имеетoccured
  3. Затем сокет-сервер уведомляет, кому он должен

Моя проблема с использованием сокетов для отправки данных с клиента на сервер - проблема аутентификации. Технически, вы не можете передавать что-либо , которое недоступно для клиентского javascript через сокет, что означает, что для аутентификации действия вам придется отправлять конфиденциальную информацию через веб-сокет. Это проблема по нескольким причинам - если ваши конфиденциальные данные могут быть доступны с помощью js на стороне клиента, здесь может быть предпринято множество атак. Также кто-то может слушать общение между ws и клиентом. Вот почему я использую вызовы API (axios и т. Д.) И храню конфиденциальные данные в файлах cookie только для http.

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

Вы также хотите, чтобы ваш сервер API оставался без состояния, то есть в вашем API нет сокетов. Я использую отдельный сервер только для соединений через веб-сокеты, и мой сервер API и сервер веб-сокетов взаимодействуют с помощью redis. Pub / sub - это действительно полезная функция для внутренней коммуникации с сервером и управления состоянием.

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

Надеюсь, это имеет смысл для вас. Этот стек сработал очень хорошо для меня.

...