sse相关知识

108 阅读2分钟

学习资料

SSE:Server-Sent Events(事件流)

SSE是一种在网页开发中使用的,基于HTTP长连接技术,允许服务器向客户端浏览器实时推送更新。

SSE的特性

  • SSE只用来传送文本,二进制数据需要转码后传送。
  • SSE默认支持断线重送。
  • 只能是单向数据流,只能由服务器向客户端推送数据。

服务器的配置

  • Content-Type:text/event-stream
  • Cache-Control:no-cache
  • Connection:keep-alive

sse(服务器推送事件)是一种用于在浏览器和服务器之间实现实时、单向通信的Web技术。它允许服务器向客户端推送数据,而无需要客户端发起请求。SSE建立一种持久的持续,通过这个连接,服务器可以随时向客户端发送更新的数据。这种实时数据的方式很适用于需要实时更新数据的应用,如聊天应用、股票行情、实时监控。

sse的原理

  • 客户端通过创建一个EventSource对象与服务器建立连接。
  • 服务器通过发送特定格式的事件流,如message事件,将数据推送给客户端。
  • 客户端通过监听EventSource对象的事件,如message事件,来接收服务器发送的数据。
  • 服务器可以根据需要发送不同的事件,如message事件,open事件,error事件。

sse建立连接的过程

  1. 客户端启动一个SSE连接:客户端使用EventSource接口创建一个到服务器的连接。
  2. HTTP请求:客户端向服务器发送一个GET请求,并在请求头中加入Accpet:text/event-stream表明这是一个SSE连接请求。
  3. 服务器响应:服务器处理这个请求后,保持该连接打开,并设置响应头Content-Type:text/event-stream,告诉客户端后续的内容将是事件流。
  4. 发送消息:服务器周期性地发送格式化的消息数据给客户端,每条消息都是纯文本,以data:开发,后面是消息内容,并以连续两个换行符\n\n结束。

本地模拟服务器代码:

const express = require("express");
const fs = require("fs");
const { clearInterval } = require("timers");
const app = express();
app.get("/api/sse", (req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Access-Control-Allow-Origin": "*",
  });
  const data = fs.readFileSync("./index.txt", "utf8");
  const arr = data.split("");
  let current = 0;
  let timer = setInterval(() => {
    if (current >= arr.length) {
      clearInterval(timer);
    } else {
      res.write(`id:${current}\n`);
      res.write("event:lol\n");
      res.write(`data:${arr[current++]}\n\n`);
    }
  }, 300);
});

app.listen(3000, () => {
  console.log("server is running");
});

本地客户端代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="data"></div>
  <script src="./sse.js"></script>
</body>
</html>
document.addEventListener("keydown", (e) => {
  if (e.key == "Enter") {
    const sse = new EventSource("http://localhost:3000/api/sse");
    sse.addEventListener("open", (e) => {
      console.log(e.target);
    });

    sse.addEventListener("lol", (e) => {
      document.getElementById("data").innerHTML += e.data;
    });

    sse.onerror = (e) => {
      console.log(e);
    };
  }
});