目錄

SSE 介紹

隨著 已生活工作中的一部分,介紹其中一種服務(wù)器端推送技術(shù)——-Sent (SSE),并簡(jiǎn)單實(shí)現(xiàn)其效果。

SSE 是一種 技術(shù),它允許服務(wù)器向客戶端發(fā)送事件,從而實(shí)現(xiàn)服務(wù)器端推送。相對(duì)于 或長(zhǎng)輪詢技術(shù),SSE 提供了更簡(jiǎn)單的方式來(lái)實(shí)現(xiàn)服務(wù)器端推送,并且支持更廣泛的客戶端和服務(wù)器端。

在 SSE 中,客戶端通過(guò)向服務(wù)器端發(fā)送一個(gè) HTTP 請(qǐng)求,請(qǐng)求某個(gè)資源,并且指定響應(yīng)的類(lèi)型是"text/-"。服務(wù)器端在響應(yīng)請(qǐng)求時(shí),將數(shù)據(jù)格式化為事件流的形式,并通過(guò) HTTP 響應(yīng)發(fā)送回客戶端。客戶端通過(guò)事件流中的數(shù)據(jù),可以實(shí)現(xiàn)實(shí)時(shí)地更新 UI 等操作。

下面是一個(gè) SSE 的 Demo,展示了如何通過(guò) SSE 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的服務(wù)器端推送應(yīng)用。

服務(wù)端代碼:

const express = require('express');
const app = express();
const port = 編程3600;
app.get('/stream', (req, res) => {
  const { message = '' } = req.query
  // 3個(gè)請(qǐng)求頭重點(diǎn),需要返回text/event-stream,告知瀏覽器以何種類(lèi)型解析
  res.set({
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
  });
  let step = 0;
  // 定時(shí)器依次返回message
  const time = setInterval(() => {
    const data = { message: message[step++]};
    // 每個(gè)消息以 \n\n分割
    res.write(`data: ${jsON.stringify(data)}\n\n`);
    if (step > message.length - 1) {
      res.end()
      clearInterval(time)
    }
  }, 500);
});
app.listen(port, () => console.log(`Server running at http://localhost:${port}`));

客戶端代碼:

// 創(chuàng)建一個(gè)EventSource
const eventSource = new EventSource(`/stream?message=${message}`);
// 監(jiān)聽(tīng)服務(wù)器返回的數(shù)據(jù)
eventSource.onmessage = function (event) {
  console.log(event.data);
};
eventSource.onerror = function () {
  eventSource.close();
};

在上面的代碼中chatgpt請(qǐng)求發(fā)送異常,我們通過(guò) 對(duì)象創(chuàng)建了一個(gè) SSE 連接,并指定了服務(wù)器端的 URL。當(dāng)有事件流數(shù)據(jù)時(shí), 回調(diào)函數(shù)會(huì)被調(diào)用。 中可看到一條類(lèi)型為的請(qǐng)求,其以下內(nèi)容

一文解析ChatGPT 之 Fetch 請(qǐng)求

一文解析ChatGPT 之 Fetch 請(qǐng)求

咋和 控制臺(tái)看到的內(nèi)容不一樣?

回車(chē)后chatgpt請(qǐng)求發(fā)送異常,并未發(fā)送請(qǐng)求chatgpt請(qǐng)求發(fā)送異常,而是發(fā)送了一個(gè) 請(qǐng)求,原因又是什么呢,仔細(xì)看

一文解析ChatGPT 之 Fetch 請(qǐng)求

觀察上圖可得它發(fā)送了一個(gè) 的 POST 請(qǐng)求,服務(wù)端響應(yīng)的是一個(gè),那么 又能如何實(shí)現(xiàn)響應(yīng)呢?因?yàn)? 并沒(méi)有方法~

通過(guò)一番查找學(xué)習(xí)~主要有兩個(gè)關(guān)鍵的 API

用于發(fā)起SSE請(qǐng)求,而用于處理服務(wù)器端推送的數(shù)據(jù)。結(jié)合兩個(gè)API簡(jiǎn)單實(shí)現(xiàn)一個(gè)方法

const fetchStream = (url, params) => {
  const { onmessage, onclose, ...otherParams } = params;
  const push = async (controller, reader) => {
    const { value, done } = await reader.read();
    if (done) {
      controller.close();
      onclose?.();
    } else {
      onmessage?.(Uint8ArrayTandroidoString(value));
      controller.enqueue(value);
      push(controller, reader);
    }
  };
  // 發(fā)送請(qǐng)求
  return fetch(url, otherParams)
    .then((response) => {
      // 以ReadableStream解析數(shù)據(jù)
      const reader = response.body.phpgetReader();
      const stream = new ReadableStream({
        start(controller) {
          push(controller, reader);
        },
      });
      return stream;
    })
    .then((stream) => new Response(stream, { headers: { 'Content-Type': 'text/html' } }).text());
};

調(diào)用方法

fetchStream(`/stream?message=${message}`, {
  methojsd: 'GET',
  headers: {
    'accept': 'text/event-stream',
    'Content-Type': 'application/json',
  },
  onmessage: (res) => {
    // todo
    console.log(res);
  },
});

經(jīng)過(guò)簡(jiǎn)單封裝實(shí)現(xiàn)的應(yīng)答請(qǐng)求效果~

另外推薦一個(gè)成熟的第三方依賴(lài)-- 點(diǎn)擊查看

-Sent 相對(duì)于其他技術(shù)的優(yōu)缺點(diǎn)

與相比,SSE技術(shù)的優(yōu)點(diǎn)在于:

與長(zhǎng)輪詢技術(shù)相比,SSE技術(shù)的優(yōu)點(diǎn)在于:

總結(jié)

最后呈上一個(gè)完整的demo,地址

免責(zé)聲明:本文系轉(zhuǎn)載,版權(quán)歸原作者所有;旨在傳遞信息,不代表本站的觀點(diǎn)和立場(chǎng)和對(duì)其真實(shí)性負(fù)責(zé)。如需轉(zhuǎn)載,請(qǐng)聯(lián)系原作者。如果來(lái)源標(biāo)注有誤或侵犯了您的合法權(quán)益或者其他問(wèn)題不想在本站發(fā)布,來(lái)信即刪。