JavaScript 中的伺服器傳送事件是什麼?


什麼是 JavaScript 中的伺服器傳送事件?

在 JavaScript 中,伺服器傳送事件 (SSE) 使伺服器能夠向客戶端傳送資料。客戶端需要與伺服器建立連線以從伺服器獲取資料。

伺服器傳送事件類似於 WebSocket,因為它也建立了客戶端和伺服器之間的連線,並且可用於在雙方傳送資料。但是伺服器傳送事件允許單向通訊,這意味著伺服器可以向客戶端傳送資料,但客戶端不能向伺服器傳送資料。

讓我們構建一個使用伺服器傳送事件的即時 React 和 Node 應用程式。這裡 React 是我們的前端,Node 是我們的後端。

示例

使用者需要按照以下步驟使用即時應用程式中的伺服器傳送事件。

  • 步驟 1 - 建立一個 React 應用程式。

  • 步驟 2 - 在應用程式的專案目錄中,執行以下命令以在專案中安裝“axios”NPM 包。

npm i axios
  • 步驟 3 - 在 App() 元件中,使用“useState”鉤子更新我們從伺服器接收到的訊息。

  • 步驟 3.1 - 使用 useEffect() 鉤子在客戶端和伺服器之間建立連線。在這裡,我們需要使用 EventSource() 建構函式透過傳遞伺服器的 URL 來與伺服器建立連線。

  • 步驟 3.2 - 此外,在事件源上新增“message”事件監聽器,每當客戶端從伺服器接收訊息時,它都會呼叫 handleMessage() 函式。

  • 步驟 3.3 - 接下來,建立一個物件,該物件刪除“message”事件並關閉客戶端和伺服器之間的連線,並將其返回。

  • 步驟 4 - 在 handleMessage() 函式中,獲取我們從伺服器接收到的資料,並將其推送到“messageData”鉤子中。

  • 步驟 5 - 新增一個 HTML 程式碼,顯示我們從伺服器接收到的所有訊息。

  • 步驟 5.1 - 新增“獲取訊息”按鈕,該按鈕呼叫“sendMessage()”函式。

  • 步驟 5.2 - sendMessage() 函式從字串陣列中選擇任何隨機訊息,並使用“axios”將其傳送到伺服器。伺服器接收訊息並透過伺服器傳送事件再次將其傳送到客戶端。

  • 步驟 6 - 將以下程式碼新增到 app.js 檔案中。

import React from "react";
import { useState, useEffect } from "react";
import axios from "axios";

const App = () => {
   const [messageData, setMessageData] = useState([]);

   useEffect(() => {
      // add the client to the server
      const newConnection = new EventSource("https://:5000/addClient");
      newConnection.addEventListener("message", handleMessage);
      return () => {
         // close the event listener
         newConnection.removeEventListener("message", handleMessage);
         newConnection.close();
      };
   }, []);

   // getting message from server
   const handleMessage = (evt) => {
      const eventData = JSON.parse(evt.data);
      setMessageData((messages) => messages.concat(eventData));
   };

   // Send a random message to the server, which the server will send to the client via server-sent events
   const sendMessage = () => {
      let messages = [
         "JavaScript",
         "React",
         "Node",
         "Express",
         "MongoDB",
         "MySQL",
         "Python",
         "Django",
         "Flask",
         "Java",
         "Spring",
         "Spring Boot",
         "Spring MVC",
         "Spring Security",
         "Spring Data",
      ];
      const random = Math.floor(Math.random() * messages.length);
      axios.post("https://:5000/message", {
         message: messages[random],
      });
   };

   return (
      <div>
         <h2> Server Sent Events </h2>
         <div>
            <h4> Click the below button to get a message from the server </h4>
            <button onClick = {sendMessage}> Get message </button>
         </div>
         <div>
            <h4> All messages </h4>
            <p> Total messages: {messageData.length} </p>
            {messageData.map((item, index) => (
               <div key={index}> {item.message} </div>
            ))}
         </div>
      </div>
   );
};

export default App;
  • 步驟 7 - 使用以下命令執行伺服器。

npm start

現在,使用者需要建立一個 Node 應用程式來設定伺服器。

  • 步驟 8 - 在 Node 應用程式的專案目錄中執行以下命令以安裝 NPM 包。

npm i cors body-parser express
  • 步驟 9 - 匯入所需的 NPM 包併為應用程式設定伺服器。

  • 步驟 10 - 建立一個 API 端點以接收來自客戶端的請求。

  • 步驟 11 - 當伺服器從“addClient”收到請求時,它將呼叫“addClient()”函式。

  • 步驟 11.1 - 在 addClient() 函式內建立標頭。之後,建立一個客戶端物件,將 id 和“res”新增到其中,並推送到“allConnectedClients”陣列中。

  • 步驟 11.2 - 偵聽“close”事件,並在伺服器和客戶端之間的內容結束時從“allConnectedClients”陣列中刪除客戶端。

  • 步驟 12 - 在 sendMessage() 函式中,從客戶端獲取訊息並將其新增到“res”中。之後,呼叫 sendToClient() 函式,該函式透過伺服器端事件將相同的訊息傳送到所有客戶端。

  • 步驟 13 - 將以下程式碼新增到 app.js 檔案中。

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const PORT = 5000;
// array to store all connected clients
let allConnectedClients = [];

// add the client to the list
const addClient = (req, res) => {

   // Set headers
   const headers = {
      "Content-Type": "text/event-stream",
      Connection: "keep-alive",
   };
   
   // adding 200 response code
   res.writeHead(200, headers);

   // create a client object and add it to the list
   const id = Date.now();
   const client = {
      id,
      res,
   };
   allConnectedClients.push(client);
   console.log(`Client is connected Successfully and its id is: ${id}`);
   req.on("close", () => {
      console.log(`Client is disconnected Successfully and its id is: ${id}`);
      
      // remove the client from the list when it gets disconnected
      allConnectedClients = allConnectedClients.filter(
         (client) => client.id !== id
      );
   });
};
const sendToClient = (msg) => {

   // iterate over all clients and send the message
   allConnectedClients.forEach((singleClient) =>
      singleClient.res.write(`data: ${JSON.stringify(msg)}

`) ); }; const sendMessage = (req, res) => { // Get the message from the request body const msg = req.body; // add message to response res.json(msg); return sendToClient(msg); }; // use cors and body parser app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // adding endpoints app.get("/addClient", addClient); app.post("/message", sendMessage); // run the server app.listen(PORT, () => { console.log(`App listening on port ${PORT}`); });
  • 步驟 14 - 使用以下命令執行 Node 應用程式的程式碼。

node app.js

注意 - 使用者需要確保伺服器和客戶端執行在不同的主機上,並且需要根據伺服器的埠更改客戶端中的 API 端點。

輸出

當客戶端成功連線時,使用者將在 Node 應用程式的終端中看到以下輸出。

對於前端部分,使用者將看到以下輸出。

上述應用程式的流程

成功執行兩個伺服器後,當用戶開啟前端部分時,它將請求“addClient”端點,該端點將在伺服器和客戶端之間建立連線。

之後,當用戶單擊“獲取訊息”按鈕時,它將向“message”端點發送一個 POST 請求,並附帶特定訊息。伺服器接收訊息並透過伺服器傳送事件將其傳送回客戶端。

客戶端接收訊息,儲存訊息資料並在瀏覽器上顯示。在這裡,我們出於測試目的從客戶端傳送資料。但是,如果我們使用資料庫並在資料庫中更新任何資料,我們可以直接將更新的資料傳送到伺服器。

更新於: 2023年4月24日

1K+ 瀏覽量

開啟您的 職業生涯

透過完成課程獲得認證

開始學習
廣告