Как сервер отправлял сообщение SSE работал в средах с несколькими экземплярами сервера

У меня есть вопрос о том, как заставить SSE работать в средах с несколькими серверами.

В пользовательском интерфейсе есть два шага:

1. source = new EventSource('http://localhost:3000/stream');
   source.addEventListener('open', function(e) {
      $("#state").text("Connected")
    }, false);
  1. Пользователь в пользовательском интерфейсе может публиковать в API для обновления данных

  2. после публикации сообщения в API сервер отправляет событие в UI для обновления UI

В среде одного сервера это работало отлично, никаких проблем.

Но в средах с несколькими серверами это не будет работать. Например, у меня есть два экземпляра сервера, и пользовательский интерфейс подписан на сервер 1, затем сервер 1 запоминает соединение, но обновление данных происходит с сервера 2, при изменении данных соединение SSE на сервере 2 отсутствует. Тогда в этом senario, как сервер 2 может отправлять SSE в UI?

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

Позвольте мне пояснить это подробнее: да, и сервис 1, и сервис 2 находятся за балансировщиком нагрузки, им не обязательно иметь один и тот же URL. Интерфейс пользователя - это чистое приложение, даже мобильное приложение. Итак, если пользовательский интерфейс отправляет запрос eventSource на LB сервера server 1, то только этот экземпляр может использовать это соединение для отправки события обратно в пользовательский интерфейс, верно? Но если у нас есть несколько экземпляров сервера 1, это означает, что любой экземпляр сервера 1, кроме текущего, НЕ может отправлять событие обратно в пользовательский интерфейс. Я считаю, что это ограничение SSE, если соединение не может быть общим для всех экземпляров. Но как.

Спасибо

1 ответ

Решение

Если у вас есть два сервера с разными URL, сделайте одно SSE-соединение (с каждого клиента) с каждым сервером.

Помните об ограничениях CORS, т.е. о той же политике происхождения. (Он работает так же, как и xhr2 CORS, поэтому довольно легко найти в Google; моя книга также подробно описывает его, глава 9.)

Если у вас есть два сервера за балансировщиком нагрузки, который представляет клиентам один URL-адрес, то вам просто нужно убедиться, что балансировщик нагрузки настроен правильно. Т.е. всегда проходить через этот сокет на правильный сервер. Если внутренний сервер умирает и нуждается в замене, балансировщик нагрузки должен закрыть сокет SSE; клиент будет автоматически переподключен и получит новый внутренний сервер.

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

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