Временами нам необходимо транслировать материалы с сервера незначительными порциями длительное время. При всем при этом канал остаётся односторонним, а следовательно веб-сокеты будут избыточными. На подмогу прибывает 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")
})