无插件版
router.js
router.get('/event-test', controller.index.event);
controller/index.js
'use strict';
const Controller = require('egg').Controller;
class BaseController extends Controller {
async event() {
const stream = new PassThrough();
this.ctx.set('Content-Type', 'text/event-stream');
this.ctx.set('Connection', 'keep-alive');
this.ctx.set('Cache-Control', 'no-cache');
this.ctx.set('Access-Control-Allow-Origin', '*');
const timer = setInterval(() => {
stream.write('event:eventName\nretry:1000\nid:1\ndata: hello\n\n');
}, 1000);
stream.on('close', function() {
console.log('closed.');
clearInterval(timer);
});
this.ctx.body = stream;
}
}
}
module.exports = BaseController;
浏览器:
const event = new EventSource('http://{host}/event-test');
event.addEventListener('open', e => {
console.log('open:', e);
});
event.addEventListener('message', e => {
console.log('get event:', e);
});
event.addEventListener('error', e => {
console.log('has error:', e);
event.close();
});
// 浏览器接受到的消息中含id时,会在本地存last-event-id,在发起重连的请求中会放到reques head中
使用egg-sse
注意:
- 使用本地自定义的非localhost域名时会出现 eventsource 一直pending
- 发送的数据必须满足规则,否则可能导致浏览器端无法接受到后续的推送(比如发送stream.write('str');)