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/eventsWymaga uprawnienia listings.read.
Jakie zdarzenia przychodzą
| Zdarzenie | Kiedy |
|---|---|
LISTING_CREATED | Gracz wystawił przedmiot |
LISTING_REMOVED | Oferta została zdjęta (przez gracza albo administrację) |
LISTING_SOLD | Ktoś kupił przedmiot |
LISTING_EXPIRED | Oferta 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 Bukkita | Zdarzenie SSE |
|---|---|
ListingCreatedEvent | LISTING_CREATED |
ListingRemovedEvent (removed / admin-removed) | LISTING_REMOVED |
ListingRemovedEvent (expired / force-expire) | LISTING_EXPIRED |
TransactionCompletedEvent | LISTING_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:
: keepaliveTo 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-kluczTo 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ń
| Opcja | Domyślnie |
|---|---|
api.sse.max-connections | 64 |
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:
NEXT_PUBLIC_MARKET_SSE=false
NEXT_PUBLIC_MARKET_POLL_MS=15000Szczegóły w dziale Rynek — strona WWW.
Wyłączenie strumienia po stronie mostu
api:
sse:
enabled: falsePo zmianie: /grzybciorynekweb reload.