双向通信之SSE

简介

基于 HTTP 协议,一个客户端去从服务器端订阅一条流,之后服务端可以发送消息给客户端直到服务端或者客户端关闭该“流”

特点

  • 建立浏览器与服务器之间的通信渠道,然后服务器向浏览器推送信息
  • SSE 是单向通道,只能服务器向浏览器发送,因为流信息本质上就是下载
  • 使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议。
  • 属于轻量级,使用简单,兼容性良好

客户端

let eventSource = new EventSource('/clock'); // url可以同域,也可以跨域
let clock = document.querySelector("#clock");
// 连接打开
source.onopen = function (event) {
  // ...
};
// 监听服务器返回的消息
eventSource.onmessage = (e) => {
    let message = e.data;
    clock.innerHTML = message;

}
// 监听连接请求失败
eventSource.onerror  = function(err){
    console.log(err);
}
// 关连接
eventSource.close();
// 监听自定义事件
eventSource.addEventListener('foo', function (e) {
  var data = e.data;
  
}, false);
复制代码

服务器端

  • 事件流对应MIME格式为text/event-stream,而且其基于HTTP长连接。针对HTTP1.1规范默认采用长连接,针对HTTP1.0的服务器需要特殊设置。
  • event-source必须编码成utf-8的格式
  • 每一次发送的信息,由若干个message组成,每个message之间用\n\n分隔。每个message内部由若干字段组成,每一字段都是如下格式。
[field]: value\n
复制代码

field需要使用下面4个规范定义好的字段:

Event: 自定义事件类型
Data: 发送的数据
ID: 每一条事件流的ID
Retry: 告知浏览器在所有的连接丢失之后重新开启新的连接等待的时间,在自动重新连接的过程中,之前收到的最后一个事件流ID会被发送到服务端
复制代码

使用例子:

app.get('/clock', (req, res) => {
    res.header('Content-Type', 'text/event-stream'); // 特定
    let timer = setInterval(() => {
        res.write(`id:${counter++}\nevent:message\ndata:${new Date().toLocaleDateString()}\n\n`);
    }, 1000);
    res.on('close', () => {
        clearInterval(timer);
    })
});

复制代码

ssestream pass through 一种转换流

app.get('/clock', (req, res) => {
    const sseStream = new SseStream(req);
    sseStream.pipe(res);
    const pusher = setInterval(() => {
        sseStream.write({
            id: counter++,
            event: 'message',
            retry: 20000, // 告诉客户端,如果断开连接后,20秒后再重试连接
            data: new Date().toLocaleDateString()
        });
    }, 1000); 
    res.on('close', () => {
      clearInterval(pusher);
      sseStream.unpipe(res);
    })
    
});

复制代码

转载于:https://juejin.im/post/5cd120fff265da03775c667b

你可能感兴趣的:(双向通信之SSE)