之前写过两篇文章,分别是《前端抢后端饭碗 — Node.js + Socket.io 制作简易聊天室》和《koa + socket.io 制作简易聊天室》,实质上都是利用了浏览器的websocket属性进去前后端的消息交流。今天我们要介绍另外一种比较新但更为简洁的消息传输方式,eventsource。下面是关于eventsource的浏览器支持情况。除了IE和Opera Mini之后,其它浏览器的支持情况良好。除了浏览器的兼容性问题之外,eventsource其实 写起来更为简洁方便。 首先是前端的代码:var evtSource = new EventSource("xxxxxxxxxx");
evtSource.onmessage = function(e) {
var res = JSON.parse(e.data);
// 其它操作
}前端代码只需要通过onmessage事件就可以获得后台传过来的数据。或者,可以监听其它的事件,如下:evtSource.addEventListener("ping", function(e) {
//其它操作
}, false);至于后台的代码,网上流传是大部份是php的版本。甚至连MDN上的都是。我们AlloyTeam的iPresst则使用了koajs开发,因此也使用js开发我们的消息系统。将status设为200是必不可少的,另外也需要设置content-type, connection, cache-control的字段。access-control-allow-origin是可选的,规定什么地址的请求会被允许。 exports.msg = function*() {
const response = {
retcode: 0,
count: 0,
};
// 数据库操作
this.status = 200;
this.set('Content-Type', 'text/event-stream');
this.set('Connection', 'keep-alive');
this.set('Cache-Control', 'no-cache');
this.set('Access-Control-Allow-Origin', '*');
// 延迟10秒
let r = 'retry: 10000\n';
r += 'data: {"count": ' + JSON.stringify(response.count) + '}\n\n';
this.body = r;
};后台传回来的消息就需要如下的格式:id: 1
event: ping
data: {count: 0}
retrey :10000字段 (参考《使用服务器发送事件》)规范中规定了下面这些字段:event事件类型.如果指定了该字段,则在客户端接收到该条消息时,会在当前的EventSource对象上触发一个事件,事件类型就是该字段的字段值,你可以使用addEventListener()方法在当前EventSource对象上监听任意类型的命名事件,如果该条消息没有event字段,则会触发onmessage属性上的事件处理函数.data消息的数据字段.如果该条消息包含多个data字段,则客户端会用换行符把它们连接成一个字符串来作为字段值.id事件ID,会成为当前EventSource对象的内部属性”最后一个事件ID”的属性值.retry一个整数值,指定了重新连接的时间(单位为毫秒),如果该字段值不是整数,则会被忽略.也就是说,你希望后台每几毫秒给前台传消息,那就填多少毫秒。