Трябва ли да има само един обект EventSource за приложение?

Когато използвате Изпратени от сървъра събития, трябва ли клиентът да установи множество връзки, за да получава различни събития, от които се интересува, или трябва да има една връзка и клиентът посочва какво го интересува по отделен канал? IMO последното изглежда по-предпочитано, въпреки че за някои може да направи клиентския код по-сложен. Спецификацията поддържа именувани събития (събития, които се отнасят до определена тема), което според мен предполага, че връзката за изпратени от сървъра събития трябва да се използва като единичен канал за всички събития.

Следният код илюстрира първия сценарий, при който се инициират множество връзки за изпратено от сървъра събитие:

var EventSource eventSource1 = new EventSource("events/topic1");
eventSource1.addEventListener('topic1', topic1Listener, false);

var EventSource eventSource2 = new EventSource("events/topic2");
eventSource2.addEventListener('topic2', topic2Listener, false);

eventSource1 ще получи събития "topic1", а eventSource2 ще получи събития "topic2". Въпреки че това е доста просто, но също така е и доста неефективно с висящ GET, възникващ за всяка тема, от която се интересувате.

Алтернативата е нещо като следното:

var EventSource eventSource3 = new EventSource("/events?id=1234")
eventSource3.addEventListener('topic3', topic3Listener, false);
eventSource3.addEventListener('topic4', topic4Listener, false);

var subscription = new XMLHttpRequest();
subscription.open("PUT", "/events/topic3?id=1234", true);
subscription.send();

В този пример ще съществува един EventSource и интересът към конкретно събитие ще бъде посочен чрез отделна заявка с връзката на събитието, изпратено от сървъра, и регистрацията ще бъде свързана с параметъра id. topic3Listener ще получи събития "topic3", а topic4Listener не. Въпреки че се изисква малко повече код, предимството е, че се прави само една връзка, но събитията могат да бъдат идентифицирани и обработени по различен начин.

Има редица примери в мрежата, които показват използването на именувани събития, но изглежда, че имената на събитията (или темите) са известни предварително, така че не е необходимо клиент да регистрира интерес към сървъра (пример). Въпреки че все още не съм видял пример, показващ множество обекти на EventSource, също така не съм виждал пример, показващ клиент, използващ отделна заявка за регистриране на интерес към определена тема, както правя по-горе. Моята интерпретация на спецификацията ме кара да вярвам, че посочването на интерес към определена тема (или име на събитие) зависи изцяло от разработчика и че може да се направи статично, като клиентът знае имената на събитията, които ще получи или динамично, като клиентът предупреждава сървъра, че се интересува от получаване на определени събития.

Ще ми е много интересно да чуя мнението на други хора по темата. NB: Обикновено съм Java разработчик, така че моля да ме извините за посредствения ми JS код.. :)


person James Tyrrell    schedule 26.07.2012    source източник
comment
не можете да използвате всички имена на събития във вашия поток от събития, вместо това можете да слушате събитие за съобщение и в event.data можете да кодирате вашия topicId и допълнителна информация   -  person 4esn0k    schedule 27.07.2012
comment
Да, разбира се, но това би означавало, че трябва да кодирам такива данни в полезен товар, което всъщност няма смисъл, когато идентификацията на съобщението вече е част от рамката на данните на спецификацията.   -  person James Tyrrell    schedule 31.07.2012
comment
+1 ! много добър въпрос. Какво направи в крайна сметка? Аз също мисля да използвам втория подход. Ще съм благодарен, ако споделите дали сте срещали проблеми с него.   -  person 2020    schedule 07.06.2013
comment
@JamesTyrrell кое решение избра? Бихте ли споделили опита си с няколко думи (или дори по-добре в статия на medium.com :))?   -  person Sergii Stotskyi    schedule 09.06.2017


Отговори (2)


Бих силно препоръчал, IMHO, да имате един EventSource обект на услуга, предоставяща SSE, и след това да излъчвате съобщенията, използвайки различни типове.

В крайна сметка обаче зависи от това колко подобни са типовете съобщения. Например, ако имате 5 различни типа съобщения, свързани с потребители, имайте потребител EventSource и разграничете с типове събития.

Ако имате един тип събитие за потребители и друг за сандвичи, бих казал, че ги съхранявайте в различни услуги и по този начин EventSources.

Добра идея е да помислите за разбиването на EventSources по същия начин, по който бихте направили спокойна услуга. Ако не бихте получили две неща от една и съща услуга с AJAX, вероятно не трябва да ги получавате от един и същи EventSource.

person saml    schedule 08.10.2012
comment
Това мащабира ли се? - person nilskp; 01.12.2017

В отговор на неясното и разрешително стандартно тълкуване на браузъра* доставчиците на браузъри непоследователно са въвели ограничения за броя на постоянните връзки, разрешени към един домейн/порт. Тъй като всеки приемник на събитие към асинхронен контекст предполага едно разпределение на постоянна връзка, докато този приемник е отворен, от решаващо значение е броят на слушателите на EventSource да бъде строго ограничен, за да се избегне превишаването на вариращите, специфични за доставчика ограничения. На практика това ви ограничава до около 6 контекстни двойки EventSource/async на приложение. Деградацията е изящна (напр. допълнителни заявки за връзка с EventSource просто ще изчакат, докато се освободи слот), но имайте предвид, че трябва да има налични връзки за извличане на ресурси на страницата, отговаряне на XHR и т.н.

*W3C издаде стандарти по отношение на постоянните връзки, които съдържат език „… ТРЯБВА да ограничи броя на едновременните връзки…“ Този език означава, че стандартът не е задължителен, така че съответствието на доставчика е променливо. http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4

person Roger Leuthner    schedule 29.01.2015