Grzybcio Wiki
GrzybcioRynekWeb

Zdarzenia na żywo (SSE)

Strumień Server-Sent Events — jakie zdarzenia leci, skąd pochodzą i jak się do niego podłączyć.

Zamiast odpytywać API co kilka sekund, strona może podłączyć się do strumienia zdarzeń i dostawać zmiany od razu, gdy zajdą na serwerze.

GET /api/v1/events

Wymaga uprawnienia listings.read.

Jakie zdarzenia przychodzą

ZdarzenieKiedy
LISTING_CREATEDGracz wystawił przedmiot
LISTING_REMOVEDOferta została zdjęta (przez gracza albo administrację)
LISTING_SOLDKtoś kupił przedmiot
LISTING_EXPIREDOferta wygasła

Format wiadomości:

event: LISTING_CREATED
data: {"event":"LISTING_CREATED","listingId":123}

Skąd te zdarzenia pochodzą

Most nie zgaduje ani nie odpytuje rynku w pętli — nasłuchuje eventów Bukkita emitowanych przez GrzybcioRynek:

Event BukkitaZdarzenie SSE
ListingCreatedEventLISTING_CREATED
ListingRemovedEvent (removed / admin-removed)LISTING_REMOVED
ListingRemovedEvent (expired / force-expire)LISTING_EXPIRED
TransactionCompletedEventLISTING_SOLD

Dlaczego usunięcie i wygaśnięcie to dwa różne zdarzenia

Po stronie rynku oba są tym samym eventem, różnią się tylko powodem. Most rozdziela je na dwa typy, żeby strona mogła je inaczej pokazać — „sprzedane" to co innego niż „przepadło, bo minął termin".

Heartbeat

Co api.sse.heartbeat-seconds (domyślnie 15) most wysyła komentarz:

: keepalive

To nie jest zdarzenie — klient go ignoruje. Chodzi o to, żeby proxy i load balancery nie zamykały połączenia, na którym „nic się nie dzieje".

Jeśli stoisz za nginxem

Nginx domyślnie buforuje odpowiedzi, co psuje SSE. W konfiguracji lokalizacji dodaj:

proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;

Uwierzytelnianie strumienia

Przeglądarkowe EventSource nie pozwala ustawić własnych nagłówków. Dlatego wyłącznie dla strumienia zdarzeń most przyjmuje klucz w parametrze zapytania:

GET /api/v1/events?api_key=twoj-klucz

To jedyne miejsce, gdzie klucz trafia do adresu URL

Klucze w URL-ach lądują w logach serwera, proxy i historii przeglądarki. Dlatego:

  • używaj tego tylko dla /api/v1/events,
  • najlepiej niech połączenie nawiązuje serwer strony, a nie przeglądarka gracza — wtedy klucz w ogóle nie opuszcza twojej infrastruktury,
  • jeśli musisz wystawić to przeglądarce, wydaj osobny klucz tylko z listings.read, żeby jego wyciek nic więcej nie odsłonił.

Limit połączeń

OpcjaDomyślnie
api.sse.max-connections64

Po przekroczeniu limitu nowe połączenia są odrzucane. Jeśli twoja strona otwiera strumień dla każdego odwiedzającego osobno, ten limit skończy się szybciej, niż myślisz — dlatego lepszym wzorcem jest jeden strumień po stronie serwera strony.

Klient powinien robić reconnect

Połączenia SSE potrafią się zrywać — restart serwera, chwilowa utrata sieci, timeout proxy. Przeglądarkowe EventSource samo ponawia połączenie; własny klient powinien robić to samo, najlepiej z rosnącym odstępem między próbami.

Gdy SSE nie wchodzi w grę

Na hostingach serverless (na przykład Vercel) długo żyjące połączenia są ucinane przez limit czasu funkcji. Wtedy wyłącz SSE po stronie strony i wróć do odpytywania:

.env.local
NEXT_PUBLIC_MARKET_SSE=false
NEXT_PUBLIC_MARKET_POLL_MS=15000

Szczegóły w dziale Rynek — strona WWW.

Wyłączenie strumienia po stronie mostu

plugins/GrzybcioRynekWeb/config.yml
api:
  sse:
    enabled: false

Po zmianie: /grzybciorynekweb reload.

On this page