概述
服务器推送事件(Server-Sent Events,简称SSE),是浏览器向服务器发送一个HTTP请求后,服务器不断单向地向浏览器推送“信息”(message),本质上,这种通信是以流信息的方式完成的一次用时很长的下载。
特点
- SSE使用HTTP协议,现有的服务器软件都支持
- SSE属于轻量级,使用简单
- SSE默认支持断线重连
- SSE一般只用来传送文本,二进制数据需要编码后传送
- SSE支持自定义发送的消息类型
用法
客户端
- 
EventSource 对象 
 SSE的客户端API部署在EventSource对象上,使用SSE时,浏览器首先生成一个EventSource实例,向服务器发起连接let source; if ('EventSource' in window) { source = new EventSource('/api/stream'); } 复制代码EventSource可指定两个参数,url和withCredentials
 url:EventSource实例的url属性返回连接的网址(请求地址)
 withCredentials:EventSource实例的withCredentials属性返回一个布尔值,表示当前实例是否开启CORS的withCredentials,默认值是false
- 
readyState 属性 
 表明连接的当前状态,可取以下值:
 0:相当于常量EventSource.CONNECTING,表示连接还未建立,或者断线正在重连
 1:相当于常量EventSource.OPEN,表示连接已经建立,可以接受数据
 2:相当于常量EventSource.CLOSED,表示连接已断,且不会重连
- 
方法 
 onopen:连接一旦建立,就会触发open事件,可在onopen属性定义回调函数source.onopen = function(event) { console.log('onopen event= ', event); }; // 另一种写法 source.addEventListener('open', function(event) { console.log('onopen event= ', event); }, false); 复制代码onerror:如果发生通信发生错误或连接中断触发 error事件source.onerror = function(event) { console.log('onerror event= ', event); }; // 另一种写法 source.addEventListener('error', function(event) { console.log('onerror event= ', event); }, false); 复制代码onmessage:客户端收到服务器发送回来的数据就会触发 message事件source.onmessage = function(event) { console.log('onmessage event= ', event); }; // 另一种写法 source.addEventListener('message', function(event) { console.log('onmessage event= ', event); }, false); 复制代码自定义事件:默认情况下,服务器发送回来的数据总是触发 message事件,我们可以自定义SSE事件,这种情况下,发送回来的数据不会触发message事件source.addEventListener('connecttime', function(event) { console.log('自定义事件:', event); }, false); 复制代码close:用于关闭SSE连接 source.close(); 复制代码
- 
代码 
const _this = this;
// 创建EventSource实例对象
const source = new EventSource('/api/stream');
// 连接一旦建立,调用该方法
source.onopen = function(event) {
    console.log('onopen= ', event);
    _this.isVisible = true;
};
// 错误
source.onerror = function(event) {
    console.log('onerror= ', event);
};
// 默认事件
source.onmessage = function(event) {
    console.log('onmessage= ', event.data);
};
// 监听自定义progress方法
source.addEventListener('progress', function(event) {
    console.log('progress= ', event);
    _this.percentage = ~~event.data;
    if (_this.percentage >= 100) {
        // 关闭连接
        source.close();
    }
}, false);
复制代码服务端
- 数据格式
服务端向浏览器发送的SSe数据,必须是UTF-8编码的文本,具有如下的HTTP头信息:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
复制代码注:Content-Type必需指定为text/event-stream
- 
字段 每一次发送的信息,由若干个 message组成,每个message之间用\n\n分隔。每个message内部由若干行组成,每一行的格式如下:[field]: value\n 复制代码data:数据内容。 data: message\n\n 复制代码如果数据很长,可以分成多行,最后一行用 \n\n分隔,中间每行用\ndata: begin message\n data: continue message\n\n 复制代码JSON数据: data: {\n data: data: [],\n data: message: '操作成功',\n data: status: 0\n data: }\n\n 复制代码event:表示自定义的事件类型,默认是 message事件。浏览器用addEventListener()监听。event: connecttime\n data: ${new Date()}\n\n 复制代码id:数据标识符,相当于每一条数据的编号。浏览器用 lastEventId属性读取这个值。一旦连接断线,浏览器会发送一个HTTP头,里面包含一个特殊的Last-Event-ID头信息,用来帮助服务端重建连接。因此,这个头信息可以被视为一种同步机制。retry: 指定浏览器重新发起连接的时间间隔。 retry: 10000\n 复制代码导致浏览器重新发起连接: 
 ① 时间间隔到期
 ② 由于网络错误等原因,导致连接出错
- 
代码 
const http = require('http');
http.createServer(function(req, res) {
    let 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": "*"
        });
        // 指定浏览器重新发起连接的时间间隔:10s
        res.write('retry: 10000\n');
        // 自定义事件:connecttime
        res.write(`event: connecttime\n`);
        // 自定义事件返回数据,以\n\n结束
        res.write(`data: ${new Date()}\n\n`);
        let id = 0;
        let timer = setInterval(() => {
            // 默认事件标识符
            res.write(`id: ${id++}\n`);
            // 默认事件返回数据
            res.write(`data: ${new Date()}\n\n`);
        }, 1000);
        req.connection.addListener('close', function() {
            clearInterval(timer);
        }, false);
    }
}).listen(3000, '127.0.0.1');
复制代码




















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
