Некоторые из событий, отправленных сервером, потеряны при повторном подключении EventSource

В нашем приложении у нас есть SSE-соединение со временем жизни 5 минут, через 5 минут сервер закрывает соединение и клиент подключается автоматически.

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

Таким образом, есть временные интервалы 1-2 секунды, когда мы можем потерять события.

Как мы можем справиться с этим делом? Каково твое мнение ?

На мой взгляд, у нас есть только один выбор: после каждого повторного подключения SSE выполнять дополнительные запросы GET на сервере для обновления данных.


person Vovan    schedule 11.10.2019    source источник
comment
почему ты отключаешься и подключаешься заново?   -  person Sudhakar Ramasamy    schedule 12.10.2019
comment
@SudhakarRS, SSE работает поверх HTTP-соединения. В нашей текущей инфраструктуре у нас есть ограничение на тайм-аут простоя HTTP на балансировщике нагрузки.   -  person Vovan    schedule 12.10.2019


Ответы (2)


Это именно то, что HTTP-заголовок Last-Event-ID в протокол SSE предназначен для.

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

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

В главе 5 моей книги Data Push Apps with HTML5 SSE я утверждаю, что вы также должны явно включить этот же уникальный идентификатор в пакет данных JSON, который вы отправляете, и вы должны поддерживать Last-Event-ID, передаваемый в качестве аргумента POST / GET как Что ж. Это дает вам гибкость для работы с альтернативными подходами к SSE с длительным опросом, а также означает, что он может работать, если повторное подключение было выполнено на стороне клиента, а не на стороне сервера. (Первое предназначено для поддержки старых браузеров, хотя это имеет все меньшее и меньшее значение по мере того, как IE вымирает; второе может потребоваться, если вы реализуете свой собственный механизм поддержания активности.)

person Darren Cook    schedule 14.10.2019
comment
Вау, спасибо, @Darren, мне нужно проверить твою книгу. Из вашего ответа я могу предположить, что на сервере нам нужно сохранить очередь сообщений, но насколько большой должна быть эта очередь, должен ли я хранить все события? - person Vovan; 14.10.2019
comment
@Vovan я должен хранить все события? Это идеальный вариант, но против него могут быть коммерческие причины. Судя по вашему описанию, похоже, что 5-секундная очередь покрывает 1-2-секундные промежутки, которые вы видите? Так что где-то между 5 секундами и вечностью :-) - person Darren Cook; 14.10.2019
comment
Спасибо, @Darren! Вы дали мне идею. Не могли бы вы также прокомментировать здесь stackoverflow.com/ questions / 57325517 / - person Vovan; 14.10.2019

Вы можете ставить события в очередь на сервере и удалять события, когда клиент активен.

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

Когда клиент подключен, удалите все события из очереди.

Вместо того, чтобы отправлять сообщение напрямую клиентам, приложение отправляет его брокеру. Затем брокер отправляет сообщение всем подписчикам (включая исходного отправителя), и они отправляют его клиентам.

Обратитесь к https://www.tpeczek.com/2017/09/server-sent-events-or-websockets.html

person Sudhakar Ramasamy    schedule 13.10.2019