Page 259 - Web性能权威指南
P. 259

段中提取有效载荷,检查可选的 ID 和类型,最后再分派一个 DOM 事件告知应用。
                 如果存在某个类型,那么就会触发自定义的 DOM 事件处理程序;否则,就会调用
                 通用的 onmessage 回调,参见 16.1 节“EventSource API”。



                                   SSE 中的 UTF-8 编码与二进制传输
                   EventSource 不会对实际载荷进行任何额外处理:从一或多个 data 字段中提取出
                   来的消息,会被拼接起来直接交给应用。因此,服务器可以推送任何文本格式
                  (例如,简单字符串、JSON,等等),应用必须自己解码。
                   话虽如此,但所有事件源数据都是 UTF-8 编码的:SSE 不是为传输二进制载荷而
                   设计的!如果有必要,可以把二进制对象编码为 base64 形式,然后再使用 SSE。
                   但这样会导致很高(33%)的字节开销,参见 11.7 节“嵌入资源”。
                   担心 UTF-8 编码也会造成高开销? SSE 连接本质上是 HTTP 流式响应,因此响
                   应是可以压缩的(如 gzip 压缩),就跟压缩其他 HTTP 响应一样,而且是动态压
                   缩!虽然 SSE 不是为传输二进制数据而设计的,但它却是一个高效的机制——只
                   要让你的服务器对 SSE 流应用 gzip 压缩。
                   不支持二进制传输是有意为之的。SSE 的设计目标是简单、高效,作为一种服务
                   器向客户端传送文本数据的机制。如果你想传输二进制数据,WebSocket 才是更
                   合适的选择。


                 最后,除了自动解析事件数据,SSE 还内置支持断线重连,以及恢复客户端因断线
                 而丢失的消息。默认情况下,如果连接中断,浏览器会自动重新连接。SSE 规范建
                 议的间隔时间是 2~3  s,这也是大多数浏览器采用的默认值。不过,服务器也可以
                 设置一个自定义的间隔时间,只要在推送任何消息时向客户端发送一个 retry 命令
                 即可。

                 类似地,服务器还可以给每条消息关联任意 ID 字符串。浏览器会自动记录最后一
                 次收到的消息 ID,并在发送重连请求时自动在 HTTP 首部追加“Last-Event-ID”
                 值。下面看一个例子:

                    (既有 SSE 连接)
                     retry: 4500 ➊
                     id: 43 ➋
                     data: Lorem ipsum
                    (连接断开)
                    (4500 ms 后)
                     => 请求


                                                                       服务器发送事件   |   247
   254   255   256   257   258   259   260   261   262   263   264