Steamovanie eventov konkretnym uzivatelom pomocou SSE a AMQP v Springu

Ahojte, mam rabitovy listenery ktore odchytavaju rozne typy eventov, nieco take:

Kód: [Vybrat]
@RabbitHandler
public void processEvent(NewMessageEvent content) {
     // publish to specific user
}

@RabbitHandler
public void processEvent(NewGroupeventCreated content) {
     // publish to specific user
}

Moja predstava by bola taka, ze uzivatel prevola SSE controller, a uvedene listenery mu budu apendovat relevantne eventy. Viete ma prosim trosku nasmerovat, ako na to, a ci je vobec mozne pomocou SSE streamovat specificke eventy konkretnym uzivatelom? Dakujem.


luvar

  • ***
  • 240
    • Zobrazit profil
    • E-mail
Re:Steamovanie eventov konkretnym uzivatelom pomocou SSE a AMQP v Springu
« Odpověď #1 kdy: 11. 05. 2020, 08:27:19 »
SSE je vcelku jednoduche a zaroven ine... Nie je to celkom klasicke imperativne programovanie, nakolko je to posielanie eventov pripojenemu klientovi. Odporucam mrknut tutorial tuna: https://www.baeldung.com/spring-server-sent-events

Prvy pristup (webflux) je vhodny, ak mate prehlad o on-blocking. Predpokladam skor, ze nie a tak odporucam druhy pristup (Sring MVC). Tam si nasledne spravite nieco ako toto:

Kód: [Vybrat]
private BindingMedziTechnologiami bindingSluzba;

@GetMapping("/stream-sse-mvc")
public SseEmitter streamSseMvc() {
    SseEmitter emitter = new SseEmitter();
    bindingSluzba.pridajKlientíkaPištíka(nejakéIdZískaťZAutentifikácieNapriklad, emitter);
    return emitter;
}

Kód: [Vybrat]
@Service
class BindingMedziTechnologiami {
   private Map<IdKlienta, SseEmitter> binding = new HashMap();
   
   public void pridajKlientíkaPištíka(IdKlienta id, SseEmitter konektivitaSSENaKlienta) {
      binding.put(id, konektivitaSSENaKlienta);
   }

   public void posliKlientoviNaprikladAMQPSpravu(IdKlienta id, Správička správa) {
        final SseEmitter  emitter = binding.get(id);
                SseEventBuilder event = SseEmitter.event()
                  .data(String.valueOf(správa))
                  .id("42")
                  .name("sse event - mvc");
                emitter.send(event);
   }
}

Strucne vysvetlenie: Ked klient pristupi na url /stream-sse-mvc, tak sa zavola metodka, ktora ulozi SseEmitter (objekt umoznujuci posielat klientovi spravy) v sluzbe BindingMedziTechnologiami do mapy. Nasledne, ked z amqp handleru chcete nieco poslat, pouzijete tu istu sluzbu, ktora z mapy vyberie emitter a posle spravu.

Co chyba, je hendling chýb, vymazavanie klientov z mapy po odhlaseni a podobne "drobnosti".

Hadam nastrel pomoze.

Re:Steamovanie eventov konkretnym uzivatelom pomocou SSE a AMQP v Springu
« Odpověď #2 kdy: 11. 05. 2020, 11:03:13 »
Citace
Strucne vysvetlenie: Ked klient pristupi na url /stream-sse-mvc, tak sa zavola metodka, ktora ulozi SseEmitter (objekt umoznujuci posielat klientovi spravy) v sluzbe BindingMedziTechnologiami do mapy. Nasledne, ked z amqp handleru chcete nieco poslat, pouzijete tu istu sluzbu, ktora z mapy vyberie emitter a posle spravu.

Co chyba, je hendling chýb, vymazavanie klientov z mapy po odhlaseni a podobne "drobnosti".

Hadam nastrel pomoze.

Podobny koncept ma tiez napadol, ale ako by sa riesilo to ak by sa dana aplikacia naskalovala? Alebo ak by uzivatel otvoril aplikaciu na dalsej karte?

luvar

  • ***
  • 240
    • Zobrazit profil
    • E-mail
Re:Steamovanie eventov konkretnym uzivatelom pomocou SSE a AMQP v Springu
« Odpověď #3 kdy: 11. 05. 2020, 15:17:09 »
Citace
Strucne vysvetlenie: Ked klient pristupi na url /stream-sse-mvc, tak sa zavola metodka, ktora ulozi SseEmitter (objekt umoznujuci posielat klientovi spravy) v sluzbe BindingMedziTechnologiami do mapy. Nasledne, ked z amqp handleru chcete nieco poslat, pouzijete tu istu sluzbu, ktora z mapy vyberie emitter a posle spravu.

Co chyba, je hendling chýb, vymazavanie klientov z mapy po odhlaseni a podobne "drobnosti".

Hadam nastrel pomoze.

Podobny koncept ma tiez napadol, ale ako by sa riesilo to ak by sa dana aplikacia naskalovala? Alebo ak by uzivatel otvoril aplikaciu na dalsej karte?

Nova karta je jednoducha. Namiesto mapy, kde si ukladate idecko klienta a k tomu jeho SSE endpoint, pouzijete multimapu (alebo mapu a druhy parameter bude list) a pri posielani dat ich budete posielat kazdej instancii SSE Endpointu daneho klienta.

Co sa tyka skalovania, to je kus zlozitejsie. Jedna sa o viac ako stovky pripojenych klientov naraz? (cca od 500 hore by som odhadol)