Page 257 - Web性能权威指南
P. 257
浏览器怎么知道每个消息的 ID、类型和范围呢?这里就用到了事件流协议。我们之
所以可以把繁重的工作托付给浏览器,就是因为这个简单的客户端 API 和定义完善
的数据格式。这两个组件总是密切协同,使得浏览器中的应用完全不必理会底层数
据协议。
使用自编 JavaScript 模拟 EventSource
SSE 最初是 HTML5 规范的补充,得到了大多数现代浏览器的原生支持。到本书
翻译时为止,只有 IE 和 Opera Mini 不支持它。最新状态请参考这里:caniuse.
com/eventsource。
不过,好在 EventSource 接口真的很简单,甚至都可以在不支持它的浏览器中使用
JavaScript 库(比如某个“腻子脚本”)来模拟它。 类似地,事件流的交付则可以
在现有的 XHR 机制基础上实现:
if (!window.EventSource) {
// 加载 JavaScript 腻子脚本
}
var source = new EventSource("/event-stream-endpoint");
...
使用腻子脚本的好处,仍然是让我们只关注应用逻辑,而不是因浏览器支持情况
闹心。话虽如此,腻子脚本只是提供了一致的 API,底层的 XHR 传输机制依旧不
那么高效:
• XHR 轮询会导致消息延迟和很高的请求开销;
• XHR 长轮询能最小化延迟,但开销还是很高;
• XHR 对流的支持有限,且在内存中缓冲所有数据。
在对高效 XHR 流没有原生支持的时候,腻子脚本可以用轮询、长轮询或 XHR 流代
替,这几种方案各有利弊。要了解详细信息,请参考 15.7 节“实时通知与交付”。
简单来讲,你得自己检查一下选择的腻子脚本,保证它能达到你的性能要求。很
多流行的库(比如 jQuery.EventSource)都使用 XHR 轮询模拟 SSE,为我们提供
了简单却不那么高效的选择。
16.2 Event Stream协议
SSE 事件流是以流式 HTTP 响应形式交付的:客户端发起常规 HTTP 请求,服务器
以自定义的“text/event-stream”内容类型响应,然后交付 UTF-8 编码的事件数据。
这么简单几句话似乎都有点说复杂了,看一个例子:
服务器发送事件 | 245