SSE流式传输,告别轮询方式

文章类型:其他

发布者:hp

发布时间:2024-11-19

一:原因

在用chatcpt时,我们看到文字是一段一段返回,发现并不是用的ws方式,那么他是用什么技术类型实现呢,

二:是什么

1:定义:SSE是一种基于HTTP协议的通信技术,允许服务器向浏览器发送更新

2:目的:(服务器->浏览器)=>流式传输

3:初衷:建议一个单向的服务器到客户端连接,使得服务器可向客户端发送数据

四:设置方式

1:参数设置

http 响应头的 contentType 设置为 text/event-stream 。

2:避免缓存

Cache-Control 设置为 no-cache

3:保持持续开启

Connection 设置为 keep-alive 。

五:使用

1:服务端

SSE 响应主要由一系列以两个换行符分隔的事件组成

字段之间用单个换行符分隔,而事件之间用两个换行符分隔

data:事件的数据。如果数据跨越多行,每行都应该以data:开始。
id:事件的唯一标识符。客户端可以使用这个ID来恢复事件流。
event:自定义事件类型。客户端可以根据不同的事件类型来执行不同的操作。
retry:建议的重新连接时间(毫秒)。如果连接中断,客户端将等待这段时间后尝试重新连接。

2:客户端,主要通过onmessage进行

const evtSource = new EventSource('path/to/sse');
evtSource.onmessage = function(event) {
    console.log(event.data); // 处理收到的数据
};

六:代码

1:服务器端

const express = require('express');
const app = express();
const PORT = 3000;

app.use(express.static('public'));

app.get('/events', function(req, res) {
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    let startTime = Date.now();

    const sendEvent = () => {
        // 检查是否已经发送了10秒
        if (Date.now() - startTime >= 10000) {
            res.write('event: close\ndata: {}\n\n'); // 发送一个特殊事件通知客户端关闭
            res.end(); // 关闭连接
            return;
        }

        const data = { message: 'Hello World', timestamp: new Date() }; 。

        res.write(`data: ${JSON.stringify(data)}\n\n`);

        // 每隔2秒发送一次消息
        setTimeout(sendEvent, 2000);
    };

    sendEvent();
});

app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});

2:客户端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>SSE Example</title>
</head>

<body>
    <h1>Server-Sent Events Example</h1>
    <div id="messages"></div>

    <script>
        const evtSource = new EventSource('/events');
        const messages = document.getElementById('messages');

        evtSource.onmessage = function(event) {
            const newElement = document.createElement("p");
            const eventObject = JSON.parse(event.data);
            newElement.textContent = "Message: " + eventObject.message + " at " + eventObject.timestamp;
            messages.appendChild(newElement);
        };
    </script>
</body>
</html>

七:兼容性

八:总结

1:SSE 确实能耗更低,且不需要客户端感知

2:单向数据发送,服务端持续性向客户端推送