Jak faktycznie działają zdarzenia wysłane przez serwer?
Więc rozumiem pojęcie zdarzeń wysyłanych przez serwer(EventSource
):
- klient łączy się z punktem końcowym poprzez
EventSource
- Klient tylko nasłuchuje wiadomości wysyłanych z punktu końcowego
Teraz to może być po prostu zły przykład, ale to trochę ma sens jak działa strona serwera, jak to Rozumiem:
- coś zmienia się w magazynie danych, np. w bazie danych
- skrypt po stronie serwera sprawdza magazyn danych co N-tą sekundę
- jeśli skrypt ankiety zauważy zmianę, Zdarzenie wysłane przez serwer zostanie wywołane do klientów
1 answers
Witryna HTML5 doctor ma świetny zapis na wysyłanych przez serwer zdarzeniach, ale postaram się podać (rozsądnie) krótkie podsumowanie również tutaj.
Zdarzenia wysłane przez serwer są w istocie połączeniem http, specjalnym typem mime (text/event-stream
) i agentem użytkownika, który dostarcza API EventSource
. Razem tworzą one fundament jednokierunkowego połączenia między serwerem a klientem, gdzie wiadomości mogą być wysyłane z serwera do klienta.
Na serwerze side, to raczej proste. Wszystko, co naprawdę musisz zrobić, to ustawić następujące nagłówki http:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Pamiętaj, aby odpowiedzieć kodem 200
, a nie 204
lub innym kodem, ponieważ spowoduje to odłączenie zgodnych agentów Użytkownika. Upewnij się również, że nie zakończysz połączenia po stronie serwera. Teraz możesz zacząć przesuwać wiadomości w dół tego połączenia. W nodejs (używając express) może to wyglądać mniej więcej tak:
app.get("/my-stream", function(req, res) {
res.status(200)
.set({ "content-type" : "text/event-stream"
, "cache-control" : "no-cache"
, "connection" : "keep-alive"
})
res.write("data: Hello, world!\n\n")
})
Na kliencie, wystarczy użyć EventSource
API, jak zauważyłeś:
var source = new EventSource("/my-stream")
source.addEventListener("message", function(message) {
console.log(message.data)
})
I to wszystko, w zasadzie.
Teraz, w praktyce, to, co się tutaj dzieje, to to, że połączenie jest utrzymywane przy życiu przez serwer i klienta za pomocą obopólnej umowy. Serwer utrzyma połączenie przy życiu tak długo, jak uzna to za stosowne. Jeśli chce, może zakończyć połączenie i odpowiedzieć 204 No Content
następnym razem, gdy klient spróbuje się połączyć. Spowoduje to, że klient przestanie próbować ponownie połączyć się. Nie jestem pewien, czy jest sposób na zakończenie połączenie w taki sposób, że klient jest informowany, aby w ogóle nie nawiązywać połączenia, tym samym pomijając klienta próbującego nawiązać połączenie raz.
Jak wspomniano, klient również utrzyma połączenie przy życiu i spróbuje ponownie połączyć się, jeśli zostanie przerwane. Algorytm do ponownego połączenia jest określony w specyfikacji i jest dość prosty.
Jeden bardzo ważny bit, który do tej pory ledwo dotknął się jednak jest typ mime. Typ mime definiuje format wiadomości schodzącej w dół łączę się. Zauważ jednak, że to nie dyktuje formatu treści wiadomości, tylko strukturę samych wiadomości. Typ mime jest bardzo prosty. Wiadomości są zasadniczo parami klucz / wartość informacji. Klucz musi być jednym z predefiniowanych zestawów:
- id-identyfikator wiadomości
- dane-dane rzeczywiste
- event-typ zdarzenia
- retry-milleseconds agent użytkownika powinien poczekać przed ponowną próbą nieudanego połączenie
Wszelkie inne klucze powinny być ignorowane. Wiadomości są następnie rozdzielane za pomocą dwóch znaków nowego wiersza: \n\n
Poniżej znajduje się prawidłowa wiadomość: (ostatnie nowe znaki linii dodane dla verbosity)
data: Hello, world!
\n
Klient zobaczy to jako: Hello, world!
.
Jak to jest:
data: Hello,
data: world!
\n
Klient zobaczy to jako: Hello,\nworld!
.
To w sumie podsumowuje, czym są zdarzenia wysyłane przez serwer: długo działające, nie buforowane połączenie http, typ mime i simple javascript API.
Aby uzyskać więcej informacji, Zdecydowanie sugeruję przeczytanie specyfikacji . Jest mały i opisuje rzeczy bardzo dobrze (chociaż wymagania Po stronie serwera mogłyby być nieco lepiej podsumowane.) Sugeruję przeczytanie go dla oczekiwanego zachowania z pewnymi kodami statusu http, na przykład.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-07 18:07:12