Server Sent Events(SSE) - co to jest?
Server Sent Events (SSE) jest mechanizmem, który pozwala na jednokierunkową komunikację pomiędzy serwerem a klientem. Możemy przy jego pomocy wysyłać wiadomości i informować klienta o zmianach na serwerze. Brzmi znajomo? Najczęściej taka funkcjonalność kojarzy nam się z Websocket? Jaka jest pomiędzy nimi różnica, kiedy powinniśmy korzystać z SEE i jak z tego skorzystać?
Websocket vs SSEIdea Server Sent Events jest podobna do Websocketów. To co różni oba rozwiązania to sposób komunikacji pomiędzy serwerem a klientem (czyli aplikacją w przeglądarce). W Websocketach mamy do czynienia z komunikacją dwukierunkową - oprócz tego, że serwer wysyła dane do klienta to klient może również wysłać odpowiedź na serwer. SSE działa trochę inaczej - wiadomości może jedynie wysyłać serwer do klienta. Jest to pewne ograniczenie ale w większości przypadków jest to wystarczająca funkcjonalność.
Kiedy wykorzystywać SSE?Tak jak wspomniałem w poprzednim akapicie wszystko zależy od tego co tworzymy. Jeśli są to różnego rodzaju chaty gdzie potrzebujemy komunikacji dwukierunkowej to oczywistym wyborem będzie Websocket. Jednak jeśli potrzebujemy żeby informować stronę o pojedynczych zdarzeniach np.:
Koniec importu dużego pliku, Koniec przetwarzania danego elementu, Zmiana na backendzie np.: zmiana danych i konieczność odświeżenia widoku,wtedy wykorzystanie SSE będzie lepszym rozwiązaniem.
Jak zaimplementować SSE?Z racji tego, że będziemy tutaj otrzymywać wiadomości z serwera implementację musimy podzielić na dwie części: klienta i serwera. Zaczniemy od części serwerowej. Aby móc wysyłać takie zdarzenia musimy ustawić odpowiednie nagłówki w odpowiedzi na zapytanie:
‘Content-Type’: ‘text/event-stream’, ‘Cache-Control’: ‘no-cache’, ‘Connection’: ‘keep-alive’,Mając tak ustawione nagłówki jesteśmy w stanie wysłać wiadomości. Wiadomości mają oczywiście swoją strukturę, której trzeba przestrzegać. Mamy tam dostępne 4 pola:
data - tutaj musimy wpisywać dane jakie chcemy przekazać do klienta w postaci striga. Jeśli potrzebujemy przekazać jakis obiekt najprościej będzie wykorzystać JSON.stringify() id - id zdarzenia event - jeśli wysyłamy kilka różnych zdarzeń możemy im nadać konkretne nazwy tak aby klient się subskrybował tylko na konkretne wiadomości retry - liczba określająca czas ponownego połączenia podczas próby wysłania zdarzeniaWiadomości przesyłamy jako zwykłe zmienne tekstowe np.: "data: 'message'". Pojedyncze wiadomości są rozdzielane podwójnym znakiem nowej linii \n\n. Przykład takiego endpointu w Express.js
const express = require('express'); const app = express(); app.get('/events', (req, res) => { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*' }); res.flushHeaders(); let i = 0; setInterval(()=>{ res.write(`id: ${i}\n`); res.write(`event: event1\n`); res.write(`data: Message -- ${Date.now()}`); res.write(`\n\n`); i++ }, 5000) }); app.listen(3000);To teraz przyszedł czas na obsługę tego po stronie klienta. Ogranicza się to tutaj tylko do wykorzystania API EventSource w przeglądarce. Podajemy tam podczas tworzenia nowej instancji obiektu adres pod którym oczekujemy otrzymywać zdarzenia
const event = new EventSource('http://localhost:3000/events')Dalsza obsługa zależy od tego jakie zdarzenia będziemy wysyłać. Tak jak wspomniałem jednym z parametrów zdarzenia może być pole event. Jeśli go podamy to musimy skorzystać z metody addEventListener
event.addEventListener('event_name', (event)=>{ // obsługa })Wszystkie inne zdarzenia są obsługiwane przy pomocy funkcji onmessage
event.onmessage = (event) => { //obsługa }I właściwie tyle. Jak widzicie jest to proste - nie potrzebujemy żadnych dodatkowych bibliotek by otrzymywać aktualizację na żywo z serwera. Jestem ciekaw czy znaliście wcześniej to rozwiązanie? No i czy z niego korzystaliście?
Chcesz więcej? Sprawdź w oryginale!
Przejdź do artykułu