LINUX.ORG.RU

Кто отвечает за persistent connection для Server-sent events?

 ,


0

2

https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events

Есть такая технология, server-sent events. И нигде я не нашел описания транспорта. То есть у нас есть EventSource, php-скрипт, и потом хренак… сообщения из похапе скрипта валшэбным образом телепортируются в браузер. Причем в любой момент, сами, без запроса.

Например, для вебсокетов прописано как апгрейдится http-соединение, формат фреймов и т.п. А для EventSource - просто «откройте им URL а дальше оно само». Но так же не бывает.

Кто может дать ссылку на секретную доку по транспортному уровню EventSource, или хотя бы на пальцах объяснить, как оно данные пушит?

★★★★★

Последнее исправление: Vit (всего исправлений: 1)

Там обычное http-соединение с chunked encoding. Клиент делает обычный GET-запрос. Сервер в него отправляет не документ целиком, как обычно, а строчки с новыми событиями, по мере их появления. На стороне браузера - какое-то апи в js есть, аналогичное ajax'у но опять же не для разового скачивания а для приёма потока.

В роли сервера может выступать даже обычный пхп с отключённой буферизацией вывода (чтобы echo сразу в сеть шло инкрементально), но для больших нагрузок разумеется нужен специализированный http-демон для транспорта событий.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

Там транспортом выступает HTTP.

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

maxcom ★★★★★
()
Ответ на: комментарий от firkax

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

но для больших нагрузок разумеется нужен специализированный http-демон для транспорта событий.

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

Vit ★★★★★
() автор топика
Ответ на: комментарий от maxcom

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

Ты отстал от жизни :). Если клиент умеет в http/2, то на все вкладки будет один коннект, в отличие от вебсокетов.

Websocket’ы такой фигней не страдают и лимит не жрут.

Могу ошибаться, но по-моему ты гонишь.

Другое дело, что вебсокеты все равно стараются в SharedWorker засунуть, чтобы сервер не нахлобучивать и траффик не раздувать.

https://github.com/nodeca/tabex - вот тут под faye писал шаринг соединения между вкладками. Теперь похоже буду полностью переделывать. Если есть пожелания - могу попробовать учесть.

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 2)
Ответ на: комментарий от maxcom

Это решаемо. На pfpmd это решили через Broadcast channel – одна вкладка подконекчена, остальные слушают её по ченелу. Если вкладка закрывается, то рандомная из открытых подсоединяется. Т.о. всегда только один коннекшен используется.

fulmar_lor
()
Ответ на: комментарий от Vit

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

Я тоже не видел, ну а что с js-дебилов взять. Имеющиеся реализации глючные, жрущие 10х ресурсов от реально нужных, итд. Ну, http не такой сложный протокол, пиши свой на си.

firkax ★★★★★
()
Ответ на: комментарий от fulmar_lor

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

И в итоге у тебя между реконнектами возникает дырка, когда эвенты пролетают.

Тут видимо надо держать 2 коннекта параллельно, и форсить подмену когда активная вкладка меняется. Либо что-то мутить с перезапросами истории (но это очень мутная тема).

В идеале коммуникации засунуть в SharedWorker, но они пока не везде есть :(. Поэтому надо изобретать фолбек.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

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

Про похапе это я просто для примера.

Ну так для чего-нибудь вроде go или erlang'а это проблемой не является.

ddidwyll ★★★★
()
Ответ на: комментарий от firkax

Я и так ментейню километры репов, еще один не нужен. Да и не великий я пейсатель на плюсах. Больше жабаскриптом пробавляюсь.

Смущает, что SSE поддерживается очень много лет, но до сих пор нет вменяемой реализации транспорта. Обычно так не бывает. Либо в протоколе какое-то фатальное говно, из-за которого его не юзают, но никому не говорят :). Из прошлых косяков был лимит на количество соединений, но http/2 этот вопрос закрыл.

Глядя со стороны - вроде фича-то удобная, обновления страниц рассылать. А все ломятся в вебсокеты. Это странно.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

И в итоге у тебя между реконнектами возникает дырка, когда эвенты пролетают.

Насколько я помню - нет, реконнект делается с последнего сообщения и всё ок.

В идеале коммуникации засунуть в SharedWorker, но они пока не везде есть :(. Поэтому надо изобретать фолбек.

Можно самому разруливать коннект и синхронизацию к примеру через sessionstorage, его onchange и window.onbeforeunload. На первый взгляд кажется не сильно сложно. Воркер конечно будет удобнее.

ddidwyll ★★★★
()
Последнее исправление: ddidwyll (всего исправлений: 1)
Ответ на: комментарий от Vit

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

Нужен сервер с асинхронным вводом-выводом. На JVM это не проблема.

maxcom ★★★★★
()
Ответ на: комментарий от Vit

Ты отстал от жизни :). Если клиент умеет в http/2, то на все вкладки будет один коннект, в отличие от вебсокетов.

Полно извращенцев которые по разным причинам не могут http/2. Как на сервере, так и на клиенте.

Могу ошибаться, но по-моему ты гонишь.

Warning: When not used over HTTP/2, SSE suffers from a limitation to the maximum number of open connections, which can be especially painful when opening multiple tabs, as the limit is per browser and is set to a very low number (6). The issue has been marked as "Won't fix" in Chrome and Firefox. This limit is per browser + domain, which means that you can open 6 SSE connections across all of the tabs to www.example1.com and another 6 SSE connections to www.example2.com (per Stackoverflow). When using HTTP/2, the maximum number of simultaneous HTTP streams is negotiated between the server and the client (defaults to 100).

(https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)

maxcom ★★★★★
()
Ответ на: комментарий от Vit

И в итоге у тебя между реконнектами возникает дырка, когда эвенты пролетают.

Над этим как раз в SSE подумали и сделали как надо, там есть возможность перезапросить события с конкретного ID.

maxcom ★★★★★
()
Ответ на: комментарий от ddidwyll

Насколько я помню - нет, реконнект делается с последнего сообщения и всё ок.

История событий усложняет все на порядок. Так тоже можно, то это когда совсем вариантов не осталось.

Можно самому разруливать коннект и синхронизацию к примеру через sessionstorage, его onchange и window.onbeforeunload. На первый взгляд кажется не сильно сложно. Воркер конечно будет удобнее.

https://github.com/nodeca/tabex я делал такую штуку. Поверь, там овердохрена нюансов. Поэтому сейчас надо будет полностью переделывать.

Все эти шины имеют заметное latency, и не контролируют фриз вкладок на мобилках. Даже если будешь юзать поллинг хартбитом - все равно остается лаг, когда все разъехалось.

Можно держать 2 коннекта параллельно. Но, как говорится, вот мы и вышли на новый уровень ада.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Смущает, что SSE поддерживается очень много лет, но до сих пор нет вменяемой реализации транспорта. Обычно так не бывает. Либо в протоколе какое-то фатальное говно, из-за которого его не юзают, но никому не говорят :).

А то что джаваскрипту ещё больше лет, но он чем дальше тем хуже используется на сайтах - не смущает? SSE это сфера интересов js-писателей, а у них всегда так.

firkax ★★★★★
()
Ответ на: комментарий от maxcom

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

Я несколько лет искренне думал что туплю, и не могу осилить прочему SSE должно хорошо работать, несмотря на явные косяки в описании и примерах. Оказалось, что там реально вопрос с транспортом никак не решен (типа, «мы вам рассказали, как можно, а дальше долбитесь как хотите»).

Vit ★★★★★
() автор топика
Ответ на: комментарий от maxcom

Да, я сейчас почитал, действительно оно отсылает id через хедер. https://html.spec.whatwg.org/multipage/server-sent-events.html#the-last-event-id-header

The Last-Event-ID` HTTP request header reports an EventSource object’s last event ID string to the server when the user agent is to reestablish the connection.

Не знал этого и костыль лишний свой написал, лол. Надо будет переделать. Спасибо.

fulmar_lor
()
Последнее исправление: fulmar_lor (всего исправлений: 1)
Ответ на: комментарий от maxcom

Нужен сервер с асинхронным вводом-выводом. На JVM это не проблема.

Это не панацея. Если у юзера нет специальных скилов, он скатится в хранение стейтов на контекстах функций. А это сильно расточительнее, чем если делать специализированный респондер под конкретную задачу, и там все ручками прописывать.

Vit ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.