Rumah >hujung hadapan web >tutorial js >Cara Menggunakan Acara Server-Sent di Node.js

Cara Menggunakan Acara Server-Sent di Node.js

Joseph Gordon-Levitt
Joseph Gordon-Levittasal
2025-02-08 09:31:09246semak imbas

How to Use Server-sent Events in Node.js

mata teras

    Server Send Events (SSE) membolehkan pelayan untuk menolak data kepada penyemak imbas pada bila-bila masa, membolehkan fungsi seperti laporan berita masa nyata, ramalan cuaca, dan harga saham. Pelayar mengeluarkan permintaan awal untuk mewujudkan sambungan, dan pelayan menyimpan sambungan terbuka untuk menghantar mesej teks.
  • SSE lebih mudah daripada WebSockets, menggunakan HTTP standard, menyokong komunikasi sehala, dan menyediakan penyambungan semula automatik. Pelayan boleh menamatkan respons SSE pada bila -bila masa, tetapi jika sambungan terganggu, penyemak imbas secara automatik akan cuba menyambung semula.
  • Pelayan boleh menyediakan bilangan URL saluran SSE atau URL akhir satu. Mesej dari pelayan mungkin mempunyai peristiwa yang berkaitan untuk mengenal pasti jenis maklumat tertentu. Pelayan juga boleh menghantar ID selepas garis data untuk menghantar semula mesej yang tidak dijawab apabila sambungan diputuskan.
  • Penyemak imbas boleh menamatkan komunikasi SSE menggunakan kaedah .close () objek Eventsource. Pelayan boleh menamatkan sambungan dengan mencetuskan res.end () atau menghantar kelewatan semula, dan kemudian mengembalikan status HTTP 204 apabila penyemak imbas yang sama cuba menyambung semula. Hanya penyemak imbas yang dapat menetapkan semula sambungan dengan membuat objek Eventsource baru.
Artikel ini akan meneroka cara menggunakan acara hantar pelayan (SSE) untuk membolehkan pelanggan menerima kemas kini automatik dari pelayan melalui sambungan HTTP. Kami juga akan meneroka penggunaannya dan menunjukkan demonstrasi praktikal bagaimana menggunakan Node.js untuk menghantar acara menggunakan pelayan.

    kelebihan pelayan menghantar acara
  • Permulaan cepat pelayan hantar acara
    • Petua penting
  • acara penghantaran pelayan lanjutan
    • saluran SSE tunggal dan berganda
    • hantar data yang berbeza pada saluran tunggal
    • menggunakan pengenal data
    • Nyatakan Retry Delay
    • Pengendali acara lain
    • menamatkan komunikasi SSE
  • Kesimpulan

Kelebihan Acara Pengiriman Server

Web bertindak balas terhadap mesej HTTP berdasarkan permintaan-tindak balas. Pelayar anda mengeluarkan permintaan URL dan pelayan mengembalikan data. Ini boleh menyebabkan penyemak imbas membuat lebih banyak permintaan kepada imej, CSS, JavaScript, dan lain -lain, dan pelayan bertindak balas. Pelayan tidak boleh menghantar mesej secara aktif ke penyemak imbas, jadi bagaimana ia menunjukkan bahawa data telah diubah? Nasib baik, anda boleh menggunakan Server Send Events (SSE) untuk menambah ciri -ciri seperti siaran berita langsung, ramalan cuaca, dan harga saham.

Ia selalu mungkin menggunakan teknologi web standard untuk mencapai kemas kini data masa nyata:

    Web 1990 -an disegarkan menggunakan halaman penuh atau bingkai/iframe.
  • Web 2000 memperkenalkan AJAX, yang boleh menggunakan pengundian lama untuk meminta data dan mengemas kini elemen DOM yang sepadan dengan maklumat baru.
Tidak ada pilihan ini yang ideal kerana penyemak imbas mesti mencetuskan penyegaran. Jika ia membuat permintaan terlalu kerap, tidak akan ada perubahan data, jadi kedua -dua penyemak imbas dan pelayan akan melakukan kerja yang tidak perlu. Jika ia meminta terlalu perlahan, ia mungkin terlepas kemas kini penting, dan harga saham yang anda ikuti telah menjunam!

Server Send Events (SSE) membolehkan pelayan menolak data ke penyemak imbas pada bila -bila masa:

  • Penyemak imbas masih membuat permintaan awal untuk menubuhkan sambungan.
  • Pelayan mengembalikan tindak balas aliran acara dan menyimpan sambungan terbuka.
  • Pelayan boleh menggunakan sambungan ini untuk menghantar mesej teks pada bila -bila masa.
  • Data masuk akan meningkatkan acara JavaScript dalam penyemak imbas. Fungsi pengendali acara mengasingkan data dan mengemas kini DOM.

Pada dasarnya, SSE adalah aliran data tanpa had. Fikirkannya sebagai memuat turun fail yang tidak terhingga yang dimuat turun dalam kepingan kecil yang boleh anda memintas dan membaca.

SSE pada asalnya dilaksanakan pada tahun 2006 dan menyokong standard ini dalam semua pelayar utama. Ia mungkin tidak dikenali sebagai WebSockets, tetapi pelayan menghantar acara lebih mudah, menggunakan HTTP standard, menyokong komunikasi sehala, dan menyediakan penyambungan semula automatik. Tutorial ini menyediakan contoh kod Node.js tanpa modul pihak ketiga, tetapi SSE boleh digunakan dalam bahasa pelayan lain, termasuk PHP.

Permulaan cepat pelayan hantar acara

Demonstrasi berikut melaksanakan pelayan web Node.js yang mengeluarkan nombor rawak antara 1 dan 1000 pada selang rawak sekurang -kurangnya setiap tiga saat.

anda boleh mencari demo node.js SSE kami di sini.

Kod ini menggunakan modul HTTP dan URL standard Node.js untuk membuat pelayan web dan menghuraikan URL:

<code class="language-javascript">import http from "node:http";
import url from "node:url";</code>

cek pelayan untuk permintaan URL masuk dan bertindak balas ketika menghadapi jalan /rawak:

<code class="language-javascript">const port = 8000;

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

  // 获取 URI 路径
  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`);</code>

Ia pada mulanya bertindak balas dengan tajuk aliran acara SSE HTTP:

<code class="language-javascript">// SSE 头
function sseStart(res) {
  res.writeHead(200, {
    Content-Type: "text/event-stream",
    Cache-Control: "no-cache",
    Connection: "keep-alive"
  });
}</code>

Fungsi lain kemudian menghantar nombor rawak dan memanggil dirinya selepas selang rawak berlalu:

<code class="language-javascript">// SSE 随机数
function sseRandom(res) {
  res.write("data: " + (Math.floor(Math.random() * 1000) + 1) + "\n\n");
  setTimeout(() => sseRandom(res), Math.random() * 3000);
}</code>

Jika anda menjalankan kod anda secara tempatan, anda boleh menggunakan curl di terminal anda untuk menguji tindak balas:

<code class="language-bash">$> curl -H Accept:text/event-stream http://localhost:8000/random
data: 481

data: 127

data: 975</code>

Tekan ctrl |. JavaScript pelanggan pelayar menghubungkan ke /uri rawak menggunakan pembina objek Eventsource:

Data masuk mencetuskan pengendali acara mesej, di mana data: rentetan selepas ia tersedia di harta .data objek acara:

<code class="language-javascript">// 客户端 JS
const source = new EventSource("/random");</code>
Petua penting

<code class="language-javascript">source.addEventListener('message', e => {
  console.log('RECEIVED', e.data);
});</code>
seperti mengambil (), penyemak imbas mengeluarkan permintaan HTTP standard, jadi anda mungkin perlu mengendalikan CSP, CORS, dan mempunyai pilihan untuk lulus parameter kedua

ke pembina Eventsource untuk menghantar cookie.

    Pelayan mesti menyimpan objek respons res berasingan bagi setiap pengguna yang disambungkan untuk menghantar data kepadanya. Ini dicapai dalam kod di atas dengan lulus nilai ke penutupan untuk panggilan seterusnya.
  • { withCredentials: true } Data mesej hanya boleh menjadi rentetan dalam data format:
  • nn (mungkin JSON). Adalah penting untuk menamatkan pulangan kereta.
  • Pelayan boleh menamatkan respons SSE pada bila -bila masa menggunakan res.end (), tetapi ... Apabila sambungan terganggu, penyemak imbas secara automatik akan cuba menyambung semula;
  • pelayan lanjutan menghantar acara

SSE tidak memerlukan lebih banyak kod daripada yang ditunjukkan di atas, tetapi bahagian berikut membincangkan pilihan lain.

saluran SSE tunggal dan berganda

Pelayan boleh menyediakan bilangan URL saluran SSE. Contohnya:

    /terkini/berita
  • /terkini/cuaca
  • /terkini/stockprice
Ini mungkin praktikal jika satu halaman menunjukkan topik, tetapi tidak jika satu halaman menunjukkan berita, cuaca, dan harga saham. Dalam kes ini, pelayan mesti mengekalkan tiga sambungan untuk setiap pengguna, yang boleh menyebabkan masalah memori sebagai peningkatan lalu lintas.

Pilihan lain adalah untuk menyediakan URL akhir titik, seperti /terkini, yang menghantar sebarang jenis data pada satu saluran komunikasi. Penyemak imbas boleh menunjukkan topik kepentingan dalam rentetan pertanyaan URL, seperti /terkini jenis = berita, cuaca, saham saham, supaya pelayan dapat mengehadkan respons SSE kepada mesej tertentu.

hantar data yang berbeza pada saluran tunggal

mesej dari pelayan boleh mempunyai

yang berkaitan yang diluluskan di atas garis event: untuk mengenal pasti jenis maklumat tertentu: data:

<code class="language-javascript">import http from "node:http";
import url from "node:url";</code>
Ini tidak mencetuskan pengendali acara "mesej" pelanggan. Anda mesti menambah pengendali untuk setiap jenis acara. Contohnya:

menggunakan pengenal data
<code class="language-javascript">const port = 8000;

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

  // 获取 URI 路径
  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`);</code>

pelayan juga boleh memilih untuk menghantar selepas baris

: data: id:

Jika sambungan diputuskan, penyemak imbas menghantar ID terakhir kembali ke pelayan dalam pengepala HTTP yang terakhir-Event-ID supaya pelayan boleh menghantar semula mesej yang tidak dijawab.
<code class="language-javascript">// SSE 头
function sseStart(res) {
  res.writeHead(200, {
    Content-Type: "text/event-stream",
    Cache-Control: "no-cache",
    Connection: "keep-alive"
  });
}</code>

ID terkini juga boleh didapati di harta tanah.

Nyatakan Retry Delay

<code class="language-javascript">// SSE 随机数
function sseRandom(res) {
  res.write("data: " + (Math.floor(Math.random() * 1000) + 1) + "\n\n");
  setTimeout(() => sseRandom(res), Math.random() * 3000);
}</code>
Walaupun penyambungan semula adalah automatik, pelayan anda mungkin tahu bahawa data baru tidak diperlukan untuk tempoh masa tertentu, jadi tidak perlu mengekalkan saluran komunikasi aktif. Pelayan boleh menghantar respons

sendiri atau sebagai sebahagian daripada mesej akhir, yang mengandungi nilai milisaat. Contohnya:

Selepas menerimanya, penyemak imbas akan meninggalkan sambungan SSE dan cuba menyambung semula selepas masa kelewatan telah berlalu. retry:

Pengendali acara lain
<code class="language-bash">$> curl -H Accept:text/event-stream http://localhost:8000/random
data: 481

data: 127

data: 975</code>

Di samping "mesej" dan acara yang dinamakan, anda juga boleh membuat "pembuka" dan "ralat" pengendali dalam klien JavaScript.

Apabila sambungan pelayan ditubuhkan, acara "terbuka" akan dicetuskan. Ia boleh digunakan untuk menjalankan kod konfigurasi lain atau memulakan elemen DOM:

Apabila sambungan pelayan gagal atau ditamatkan, peristiwa "ralat" dicetuskan. Anda boleh menyemak.

ingat, tidak perlu menyambung semula:
<code class="language-javascript">// 客户端 JS
const source = new EventSource("/random");</code>
ia akan berlaku secara automatik.

menamatkan komunikasi SSE
<code class="language-javascript">source.addEventListener('message', e => {
  console.log('RECEIVED', e.data);
});</code>

Penyemak imbas boleh menamatkan komunikasi SSE menggunakan kaedah .close () objek Eventsource. Contohnya: Pelayan boleh menamatkan sambungan dengan:

  1. mencetuskan res.end () atau hantar retry: kelewatan, kemudian
  2. Mengembalikan status HTTP 204 apabila penyemak imbas yang sama cuba menyambung semula.

Hanya pelayar boleh mewujudkan semula sambungan dengan membuat objek Eventsource baru.

Kesimpulan

Acara sisi pelayan menyediakan cara untuk melaksanakan kemas kini halaman masa nyata, yang mungkin lebih mudah, lebih praktikal dan lebih ringan daripada mengambil Ajax pengundian berasaskan (). Kerumitan terletak di sisi pelayan. Anda mesti:

  1. simpan semua sambungan aktif pengguna dalam ingatan, dan
  2. Pencetus pemindahan data apabila perubahan berlaku.

tetapi ini benar -benar di bawah kawalan anda, dan lanjutannya tidak sepatutnya lebih kompleks daripada aplikasi web lain.

Satu -satunya kelemahan adalah bahawa SSE tidak membenarkan anda menghantar mesej dari penyemak imbas ke pelayan (kecuali permintaan sambungan awal). Anda boleh menggunakan Ajax, tetapi ini terlalu lambat untuk aplikasi seperti permainan tindakan. Untuk komunikasi dua arah yang betul, anda memerlukan websocket. Sila lihat cara membuat aplikasi langsung menggunakan WebSockets di Node.js untuk mengetahui lebih lanjut!

Atas ialah kandungan terperinci Cara Menggunakan Acara Server-Sent di Node.js. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn