octombrie 12, 2024

Obiectiv Jurnalul de Tulcea – Citeste ce vrei sa afli

Informații despre România. Selectați subiectele despre care doriți să aflați mai multe

Cum să utilizați evenimentele trimise de server în Node.js — SitePoint

Cum să utilizați evenimentele trimise de server în Node.js — SitePoint

În acest articol, vom explora modul de utilizare a evenimentelor trimise de server pentru a permite clientului să primească actualizări automate de la server printr-o conexiune HTTP. De asemenea, vom analiza de ce este util acest lucru și vom arăta demonstrații practice despre cum să folosiți evenimentele trimise de server cu Node.js.

Cuprins

De ce sunt utile evenimentele trimise de server?

Web-ul se bazează pe mesajele HTTP de solicitare și răspuns. Browserul dvs. face o solicitare URL și serverul răspunde cu datele. Acest lucru poate duce la mai multe solicitări de browser și răspunsuri de server pentru imagini, CSS, JavaScript etc. Serverul nu poate face asta Iniţia mesaje către browser, deci cum poate indica faptul că datele s-au schimbat? Din fericire, puteți adăuga funcții precum știri live, rapoarte meteo și cotații bursiere cu evenimentele trimise de pe server.

Implementarea actualizărilor de date în direct folosind tehnologii web standard a fost întotdeauna posibilă:

  • Web-ul în anii 1990 folosea reîmprospătarea full-page sau iframe.
  • În anii 2000, Web-ul a introdus tehnologia Ajax, care poate folosi sondaje lungi pentru a solicita date și pentru a actualiza elementele DOM corespunzătoare cu informații noi.

Niciuna dintre opțiuni nu este ideală, deoarece browserul trebuie să declanșeze actualizarea. Dacă face solicitări prea des, nu se vor schimba date, așa că atât browserul, cât și serverul fac lucrări inutile. Dacă plasează comenzi prea încet, s-ar putea să rateze o actualizare importantă, iar prețul acțiunilor pe care le urmăriți s-ar putea prăbuși!

Evenimente trimise de server

  • Browserul face în continuare cererea inițială de a stabili o conexiune.
  • Serverul returnează răspunsul la fluxul de evenimente și menține conexiunea deschisă.
  • Serverul poate folosi această conexiune pentru a trimite mesaje text în orice moment.
  • Datele primite declanșează un eveniment JavaScript în browser. Funcția de gestionare a evenimentelor poate analiza date și poate actualiza DOM.

În esență, SSE este un flux nesfârșit de date. Gândiți-vă la asta ca la descărcarea unui fișier infinit de mare în bucăți mici pe care le puteți intercepta și citi.

SSE a fost implementat pentru prima dată în 2006 și toate browserele majore acceptă acest standard. Este poate mai puțin cunoscut decât WebSockets, dar evenimentele trimise de server sunt mai simple, folosesc HTTP standard, acceptă comunicarea unidirecțională și oferă reconectare automată. Acest tutorial oferă exemplu de cod Node.js fără module terță parte, dar SSE este disponibil în alte limbi de pe partea serverului Inclusiv PHP.

READ  Care este viitorul roboților umanoizi?

Pornire rapidă a evenimentelor trimise de pe server

Următoarea demonstrație implementează un server web Node.js care scoate un număr aleator între 1 și 1000 la un interval aleator cel puțin o dată la trei secunde.

Mai jos este demonstrația noastră Node.js SSE (puteți Deschideți-l într-o filă separată de browser Daca preferi).

Codul folosește Node.js standard http Și url Module pentru crearea unui server web și analizarea adreselor URL:

import http from "node:http";
import url from "node:url";

Serverul examinează solicitarea URL primită și reacționează când întâlnește un fișier /random drum:

const port = 8000;

http.createServer(async (req, res) => {

  
  const uri = url.parse(req.url).pathname;

  
  switch (uri) {
    case "/random":
      sseStart(res);
      sseRandom(res);
      break;
  }

}).listen(port);

console.log(`server running: http://localhost:${port}\n\n`);

Răspunde inițial cu antetul fluxului de evenimente HTTP SSE:


function sseStart(res) {
  res.writeHead(200, {
    Content-Type: "text/event-stream",
    Cache-Control: "no-cache",
    Connection: "keep-alive"
  });
}

O altă funcție trimite un număr aleator și se autoapelează după ce a trecut o perioadă aleatoare:


function sseRandom(res) {
  res.write("data: " + (Math.floor(Math.random() * 1000) + 1) + "\n\n");
  setTimeout(() => sseRandom(res), Math.random() * 3000);
}

Dacă rulați codul local, puteți testa răspunsul folosind rostogolire În terminalul dvs.:

$> curl -H Accept:text/event-stream http://localhost:8000/random
data: 481

data: 127

data: 975

El apasă Control | cataplasmă Și C Pentru a finaliza cererea.

Apelurile JavaScript din partea clientului browserului /random URI folosind Constructor al obiectului EventSource:


const source = new EventSource("/random");

Datele primite conduc la a message Managerul de evenimente unde următorul șir data: Disponibil în obiect eveniment .data Proprietate:

source.addEventListener('message', e => {
  console.log('RECEIVED', e.data);
});

Notite importante

  • Îi place Aduce()browserul dvs. face o solicitare HTTP standard, așa că poate fi necesar să lucrați cu aceasta CSP, curs Și opțional treci din nou { withCredentials: true } argument pentru EventSource Generator pentru trimiterea cookie-urilor.
  • Serverul trebuie să păstreze individul res Obiecte de răspuns pentru fiecare utilizator conectat pentru a le trimite date. Se realizează în codul de mai sus prin trecerea valorii din închidere la apelul următor.
  • Datele mesajului pot fi doar un șir (eventual JSON) trimis în format data: <message>\n\n. Retururile de transfer încheiate sunt esențiale.
  • res.end()dar…
  • Când are loc o întrerupere, browserul încearcă automat să se reconnecteze; Nu este nevoie să introduceți propriul cod de reapelare.
READ  Microsoft anunță noi funcții de accesibilitate Xbox

Evenimente avansate trimise de pe server

SSE nu necesită mai mult cod decât cel descris mai sus, dar secțiunile următoare discută mai multe opțiuni.

Un canal față de multe canale SSE

Serverul poate furniza orice număr de adrese URL de canal SSE. De exemplu:

  • /latest/news
  • /latest/weather
  • /latest/stockprice

Acest lucru poate fi practic dacă o singură pagină afișează un singur subiect, dar mai puțin dacă o singură pagină afișează știri, vreme și cotații bursiere. În acest caz, serverul trebuie să mențină trei conexiuni per utilizator, ceea ce poate duce la probleme de memorie pe măsură ce traficul crește.

O opțiune alternativă este de a furniza o singură adresă URL pentru punctul final, de ex /latestCare trimite orice tip de date pe un singur canal de comunicare. Browserul poate indica subiecte de interes în șirul de interogare URL – de ex. /latest?type=news,weather,stockprice – Pentru ca serverul să poată restricționa răspunsurile SSE la anumite mesaje.

Trimiterea de date diferite pe un canal

Mesajele de pe server pot avea un link event: Trecut pe linia de mai sus data: Identificați tipuri specifice de informații:

event: news
data: SSE is great!

event: weather
data: { "temperature": "20C", "wind": "10Kph", "rain": "25%" }

event: stock
data: { "symbol": "AC", "company": "Acme Corp", "price": 123.45, "increase": -1.1 }

Asta va Nu Mutați partea clientului "message" Organizatorul evenimentului. Trebuie să adăugați handlere pentru fiecare tip event. De exemplu:


source.addEventListener('news', e => {

  document.getElementById('headline')
    .textContent = e.data;

});


source.addEventListener('weather', e => {

  const w = JSON.parse(e.data);

  document.getElementById('weather')
    .textContent = `${ w.temperature } with ${ w.wind } wind`;

});


source.addEventListener('stock', e => {

  const s = JSON.parse(e.data);

  document.getElementById(`stock-${ s.symbol }`)
    .textContent = `${ s.share }: ${ s.price } (${ s.increase }%)`;

});

Opțional, serverul poate trimite și un mesaj id: după A data: Linia:

event: news
data: SSE is great!
id: 42

Dacă conexiunea este întreruptă, browserul îl trimite pe ultimul id Reveniți la server la Last-Event-ID Antet HTTP, astfel încât serverul să poată retrimite orice mesaj fără răspuns.

Cel mai recent ID client este disponibil și în obiectul eveniment .lastEventId Proprietate:


source.addEventListener('news', e => {

  console.log(`last ID: ${ e.lastEventId }`);

  document.getElementById('headline')
    .textContent = e.data;

});

Deși reconectarea este automată, serverul dvs. poate ști că nu sunt așteptate date noi pentru o perioadă specificată, deci nu este nevoie să mențineți un canal de conexiune activ. Serverul poate trimite un retry: Un răspuns în milisecunde fie singur, fie ca parte a mesajului final. De exemplu:

retry: 60000
data: Please don't reconnect for another minute!

La primire, browserul va renunța la conexiunea SSE și va încerca să se reconecteze după ce perioada de întârziere a trecut.

READ  Telegram adaugă un aspect spoiler media, noi instrumente de desen și imagini de profil pentru contacte

Alți handler de evenimente

Lângă "message" Și evenimentele numite, le puteți crea și pe acestea "open" Și "error" Handler-uri în JavaScript pe partea clientului.

acea "open" Evenimentul este declanșat atunci când se stabilește o conexiune la server. Poate fi folosit pentru a rula cod de configurare suplimentar sau pentru a inițializa elemente DOM:

const source = new EventSource('/sse1');

source.addEventListener('open', e => {

  console.log('SSE connection established.');

});

acea "error" Evenimentul este declanșat atunci când conexiunea la server eșuează sau se încheie. Puteți inspecta obiectul evenimentului .eventPhase Funcție pentru a verifica ce s-a întâmplat:

source.addEventListener('error', e => {

    if (e.eventPhase === EventSource.CLOSED) {
      console.log('SSE connection closed');
    }
    else {
      console.log('error', e);
    }

});

Amintiți-vă că nu este nevoie să vă reconectați: Se întâmplă automat.

Terminați conexiunile SSE

Browserul poate termina conexiunea SSE folosind obiectul EventSource .close() drum. De exemplu:

const source = new EventSource('/sse1');


setTimeout(() => source.close(), 3_600_000);

Serverul poate opri conexiunea prin:

  1. filmare res.end() Sau trimite un retry: întârziere
  2. Returnează starea HTTP 204 când același browser încearcă să se reconecteze.

Browserul poate restabili conexiunea doar prin crearea unei noi conexiuni EventSource Poartă.

Concluzie

Evenimentele din partea serverului oferă o modalitate de implementare a actualizărilor paginilor live, care este probabil mai ușoară, mai practică și mai ușoară decât Fetch()Sondaj bazat pe Ajax. Complexitate la capătul serverului. va trebui să:

  1. Păstrați toate conexiunile de utilizator active în memorie și
  2. Declanșează transferurile de date când ceva se schimbă.

Dar acest lucru este în întregime în controlul tău, iar scalarea nu ar trebui să fie mai complicată decât orice altă aplicație web.

Singurul dezavantaj este că SSE nu vă permite să trimiteți mesaje din browser către server (în afară de cererea inițială de conectare). Puteți folosi Ajax, dar acest lucru este prea lent pentru aplicații precum jocurile de acțiune. Pentru o comunicare corectă în două sensuri, aveți nevoie de WebSockets. Vom avea un nou tutorial despre asta în curând!