Summary
- W3C 在 2009 年 4 月 23 日发布的 Server-Sent Events 工作草案,描述了页面如何通过
EventSource接收服务器沿 HTTP 连接不断送来的事件。 - 事件可以带
id。普通断线后,浏览器以Last-Event-ID报出上次收到的位置;空的id则清掉这个位置。服务器依据自己的记录决定接下来发送什么。
股票行情停在一个数字上。你看了看屏幕,甚至会怀疑市场突然集体去喝茶。刷新之后又跳出新数字,真正麻烦的地方才出现:两次数字之间发生了什么?如果只知道“连接恢复了”,屏幕可以显得很忙,读者却仍然被蒙在鼓里。
W3C 2009 年 4 月 23 日的工作草案把这种对话做成 EventSource。页面打开一个 URL,服务器用 text/event-stream 返回持续送达的内容,浏览器按行解析,在一个事件块完成时交给页面。它仍然走 HTTP,语法却像一张克制的电报纸条:这几行是数据,那一行是编号,空行表示可以投递了。
草案中的行情例子尤其好懂。服务器连写三行 data,内容分别是 YHOO、+2、10;接下来的空行让浏览器发出一个含三行内容的事件。页面脚本再拆开它,更新行情。三行合成一条,而不是把每个数字当作独立新闻。持续打开的连接因此也能有清楚的句号。
然后来到那张小小的书签。另一个例子在 data: first event 旁写上 id: 1。浏览器收到它,就把“1”记下来。如果线路在下一条到达前断掉,新请求会带上 Last-Event-ID: 1。2009 年 12 月的 Last Call 草案继续保留这个重连安排。浏览器再次敲门时,有了可核对的位置,而不是只会说“刚才信号不太好”。
编号的力量也有边界。服务器若保存了历史事件,就可以据此挑选后续内容;若只提供眼前的新消息,浏览器手里的号码不能凭空变出漏掉的记录。保存多久、从哪个编号继续、一个交易时段结束后怎样换卷,都是流的经营者要作的决定。共享协议只负责让双方把位置说清楚。与其让浏览器猜服务器的档案,不如让它如实报告自己看到了哪一页。
草案还让这张书签可以作废。示例里的后一个事件带着一个没有值的 id 字段;浏览器会把之前记住的编号清空。再重连时,Last-Event-ID 也不会出现。这个细节很像编辑给旧卷宗贴上“到此为止”:新一轮行情不必背着旧时段的页码往前跑。编号可以帮助续读,也可以由发稿方宣布失效。
流里还有不会登上页面的声音。以冒号开头的一行是注释,浏览器读过后不派发事件。2015 年 2 月的 W3C 推荐标准提到,定时发送这种注释可以防止某些旧代理因为连接太久没有动静而把它掐断。推荐标准还描述了用 retry 调整再次连接的等待时间,以及用 HTTP 204 No Content 告诉浏览器别再重试。行情播报员既要会轻咳一声证明自己还在,也要会说今天收工了。
W3C 的发布记录把路线列得很清楚:2009 年的工作草案、2012 年的候选推荐标准快照、2015 年的推荐标准。这里最漂亮的设计并非“永远在线”的口号,而是断线那一刻的分工。浏览器知道自己最后听到什么,服务器知道自己还能提供什么。一个编号把两种知识接到一起,让续播成为可检查的决定。
这也与 Web Workers 那篇故事分得开。Worker 把费时的计算搬离页面,消息把结果带回来;EventSource 让服务器不断送来消息,编号帮双方处理线路中断。一个解决按钮被计算占住的尴尬,一个解决行情跳过一截却装作若无其事的尴尬。互联网历史里,后者同样值得记一笔。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance





