Dispersion开发记录之服务器发送事件(SSE)

Dispersion开发记录之服务器发送事件(SSE)

经过前几天的客户端API的编写,今天下午进军服务器与客户端通信了。我打算让用户与服务器之间的交流同时使用SSE和WebSocket,因为,私以为WebSocket的监听是阻塞的,无论怎么样都需要开两个连接,所以为什么其中一个连接不用更轻量级的SSE呢?

当然,最令人不悦的是,我又要缩小一次受众群体了,因为这两个功能都是基于HTML5标准的,而且我懒得去兼容低版本浏览器了。不过估计网络工程师大部分都用Chrome或者Firefox,方便调试。我本来是微软的坚定支持者,自从升级了Windows 10之后坚决不安装Chrome,直到后来Edge打不开了,我才装上Chrome…

服务器发送事件(Server sent events)

HTML5提出的新标准。我前些天在准备dispersion这个项目的时候翻看了一下w3school的H5模块,发现竟然有一直梦寐以求的同步推官方实现!但是可惜这次我不仅仅需要用到同步推,还要用到“同步发”,所以还是得用上Socket。详情见w3school。

具体关于Socket与SSE的区别,我看了PeterLiu的文章之后,验证了我的猜想。

你可能听说过Comet, Ajax推送, 反向Ajax, HTTP流,WebSockets与SSE是不同的技术。可能最大的优势是低延迟。SSE用于web应用程序刷新数据,不需要用户做任何动作。
你可能听说过HTML5的WebSockets,也能推送数据到客户端。WebSockets是实现服务端更加复杂的技术,但它是真的全双工socket, 服务端能推送数据到客户端,客户端也能推送数据回服务端。SSE工作于存在HTTP/HTTPS协议,支持代理服务器与认证技术。SSE是文本协议你能轻易的调试它。如果你需要发送大部二进制数据从服务端到客户端,WebSocket是更好的选择。
我怎么试怎么不行。后来我发现我一直信赖的w3school.com.cn竟然也是盗版!看回正版的国外w3school’s’上的教程,仔细观察缺漏之处,发现所有的消息前面要加’data: ‘!急忙改之。然后就可以了。但是我发现这种方法,即使flush(),ob_flush(),都必须等所有结果运行完成之后才能将缓存中的字符串返回。另外一个问题就是,php脚本运行完一次之后,浏览器会自动发送第二次,其中有时间间隔,意味着必须采用堵塞型才能保证消息的实时性。

.addEventListener

我后来不知道怎么找到了这个网页,发现这个网页更推荐使用EventSource的.addEventListner。分析代码,发现SSE事实上返回的是一个JSON文件,使用JSON.parse解析之后就得到了相应结构的对象。这样其实非常方便!而且经测试,功能完好。发现前面缺的一个东西是ob_end_flush(),这几个冲掉缓存的函数我还没完全搞懂。

avatar
Kerry Su