双向通讯之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会被发送到服务端
复制代码

使用例子:bash

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);
    })
    
});

复制代码
相关文章
相关标签/搜索