# 网络请求-SSE

SSE (sever sent events)与 WebSocket 作用相似,都是建立浏览器与服务器之间的通信渠道,然后服务器向浏览器推送信息。

总体来说,WebSocket 更强大和灵活。因为它是全双工通道,可以双向通信;SSE 是单向通道,只能服务器向浏览器发送,因为流信息本质上就是下载。如果浏览器向服务器发送信息,就变成了另一次 HTTP 请求。

# 使用 SSE

使用 SSE 时,浏览器首先生成一个 EventSource 实例,向服务器发起连接

var source = new EventSource(url);

连接一旦建立,就会触发 open 事件,可以在 onopen 属性定义回调函数

source.onopen = function (event) {
  // ...
};

客户端收到服务器发来的数据,就会触发 message 事件,可以在 onmessage 属性的回调函数。

source.onmessage = function (event) {
  var data = event.data;
  // handle message
};

close 方法用于关闭 SSE 连接。

source.close();

# 服务器实现

服务器向浏览器发送的 SSE 数据,必须是 UTF-8 编码的文本,具有如下的 HTTP 头信息。

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

每一次发送的信息,由若干个 message 组成,每个 message 之间用\n\n 分隔。

data: some text\n\n

data: another message\n
data: with two lines \n\n

服务器实现代码:

const http = require("http");

http
  .createServer(function (req, res) {
    var fileName = "." + req.url;

    if (fileName === "./stream") {
      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 () {
        res.write("data: " + new Date() + "\n\n");
      }, 1000);

      req.connection.addListener(
        "close",
        function () {
          clearInterval(interval);
        },
        false
      );
    }
  })
  .listen(8844, "127.0.0.1");