Server-Sent Events (Sse)

Server-Sent Events can only do one way communication. It's more suitable for Notification system.

Technically we can still design a chat application using SSE event but it will increase over-head and the technology is not meant to be used that way.

Pasted image 20230918093834.png

Applications:

  • Deployment logs
  • Real-time notifications
  • Stock markets updates

[!warning]
When not using HTTP 2, the maximum number of connection is 6. When use HTTP 2, the maximum connection is negotiable with default is 100

[!note]
When the client disconnect from the server, it will keep pinging until the connection re-established. Then it will start streaming again

Example

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Server-Sent Events Example</title>
    </head>
    <body>
        <h1>Real-time updates:</h1>
        <div id="messages"></div>

        <script>
            const eventSource = new EventSource("http://localhost:3000/events");
            eventSource.onmessage = (event) => {
                const messageElement = document.createElement("p");
                messageElement.textContent = event.data;
                document.getElementById("messages").appendChild(messageElement);
            };
        </script>
    </body>
</html>

const http = require("http");

const server = http.createServer((req, res) => {
  if (req.url === "/events") {
    res.writeHead(200, {
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      Connection: "keep-alive",
      "Access-Control-Allow-Origin": "*", // Allow requests from all origins
      "Access-Control-Allow-Methods": "GET", // Specify allowed HTTP methods
      "Access-Control-Allow-Headers": "Content-Type", // Specify allowed headers
    });

    const intervalId = setInterval(() => {
      const message = `data: ${new Date().toLocaleTimeString()}\n\n`;
      res.write(message);
    }, 1000); // Send event every second

    req.on("close", () => {
      clearInterval(intervalId);
      res.end();
    });
  } else {
    res.statusCode = 404;
    res.end("Not Found");
  }
});

server.listen(3000, () => {
  console.log("Server listening on port 3000");
});

We would then have the following

Pasted image 20240304203244.png