Server-Sent Events просто на примере

Временами нам необходимо транслировать материалы с сервера незначительными порциями длительное время. При всем при этом канал остаётся односторонним, а следовательно веб-сокеты будут избыточными. На подмогу прибывает SSE, простая, однако отчего-то всё ещё достаточно редкая технология.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>SSE</h1>
<div id="data"></div>
<script>
    const eventSource = new EventSource("http://localhost:8080/stream");
    console.log("Start stream!");
    const dataElem = document.getElementById("data");
    eventSource.onmessage = (message) => {
        dataElem.innerText = `id: ${message.lastEventId} data: ${message.data}`;
    }

    eventSource.addEventListener("end-of-stream", () => {
        console.log("End of stream!");
        eventSource.close();
    })
</script>
</body>
</html>
const http = require("http");
const fs = require("fs");
const path = require("path");

const getRandomInt = max => Math.floor(Math.random()*max);

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

    let id = 0;
    let data;
    // каждую секунду отправляем новые данные клиенту
    const timer = setInterval(() => {
        data = getRandomInt(100);
        if (data !== undefined && data !== "") {
            res.write(`data: ${data}\n`);
            res.write(`id: ${++id} \n`);
            res.write("\n");
        }
    }, 1000);

    // закроем соединение через 10 секунду
    setTimeout(() => {
        clearInterval(timer);
        res.write(`event: end-of-stream\n`);
        res.write(`data: this is the end\n`)
        res.write("\n");
        res.end("Ok");
    }, 10000)
}

http.createServer((req, res) => {
    const url = new URL(`http://${req.headers.host}${req.url}`);

    if (url.pathname === "/stream") { // по этому роуту отдаем данные
        sse(req, res);
        return;
    }

    if (url.pathname === "/send-message") { // можем отправить клиенту данные простым запросом /send-message?message=text
        data = url.searchParams.get("message");
        res.end(data);
        return;
    }

    const fileStream = fs.createReadStream(path.join(__dirname, "index.html"));
    fileStream.pipe(res);
}).listen(8080, () => {
    console.log("Server started on 8080")
})

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *