1. The Essence of SSE
Strictly speaking, the HTTP protocol cannot achieve server-initiated push. However, there is a workaround: the server declares to the client that it will send streaming information next.
In other words, what is sent is not a one-time data packet, but a continuous data stream that keeps arriving. At this point, the client does not close the connection and keeps waiting for new data streams from the server. Video streaming is a typical example. Essentially, this communication completes a long-duration download in the form of streaming information.
SSE leverages this mechanism to push information to the browser using streaming. It is based on the HTTP protocol and is supported by all browsers except IE/Edge.
SSE also has its advantages.
- SSE uses the HTTP protocol, and all existing server software supports it. WebSocket is an independent protocol.
- SSE is lightweight and simple to use; the WebSocket protocol is relatively complex.
- SSE supports automatic reconnection by default, while WebSocket requires manual implementation.
- SSE is generally used only for text transmission; binary data needs to be encoded before sending. WebSocket supports binary data transmission by default.
- SSE supports custom message types for sending.
Client:
<!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="app"></div>
</body>
</html>
<script>
var app = document.getElementById("app");
var url = "http://127.0.0.1:3000/stream";
var source = new EventSource(url, { withCredentials: true });
source.addEventListener(
"open",
function (event) {
// ...
console.log("open", event);
},
false
);
source.addEventListener(
"message",
function (event) {
var data = event.data;
console.log("[ data ]", data);
// handle message
var divContainer = document.createElement("div");
var pText = document.createTextNode(data);
divContainer.appendChild(pText);
app.appendChild(divContainer);
},
false
);
</script>
Server:
var express = require("express"); var app = express(); app.use(express.static("./")); app.get("/stream", function (req, res) { var val = 1; console.log("[ req ]", req); res.writeHead(200, { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive", "Access-Control-Allow-Origin": "*", }); res.write("retry: 10000\n"); //设置断线重连时间 res.write("event: connecttime\n"); res.write("data: " + new Date() + "\n\n"); // res.write("data: " + new Date() + "\n\n"); interval = setInterval(function () { val++; res.write("data: " + val + "-----" + new Date().getTime() + "\n\n"); }, 1000); req.connection.addListener( "close", function () { clearInterval(interval); }, false ); }); var server = app.listen(3000, function () { console.log("Example app listening on port 3000!"); });
暂无评论。