利用H5的EventSource,小试服务器推送(SSE)

H5在最后定稿的时候,出现了一个新的JS API:EventSource(也许是我之前一直没关注吧)。

EventSource有什么用呢?简单来说,就是实现Web端的服务器主动推送功能(SSE,Server-Sent-Events)。

废话少说,先上一段代码:

这段代码运行后,会开始监听服务器推送的事件,例如任意时刻,sse.php输出一句hello world,客户端的console就会立马有输出。

我们来深入了解一下。

窥探EventSource细节:

首先, new EventSource(url) ,客户端会立马向该url发出一个HTTP请求(没错,的确是HTTP请求,整个SSE都是建立在HTTP协议上面的,这是于WebSocket的本质区别),然后观察这个HTTP的Header,它的MIME类型是text/event-stream。

text/event-stream是专门为SSE设计的MIME类型,这个是构造SSE请求的关键。

当服务端收到接到请求后,会hold住这个请求,当需要服务端推送数据的时候,才往这个请求中返回所需要的信息,以 data:'这个是返回的消息内容' 格式的写入,并利用HTTP/1.1中的分块传输的机制,立马刷新缓存中,输出内容并不释放连接,当有下一个内容需要推送的时候,又立马扔到HTTP的返回中。

上面的流程是不是很熟息?和以前的长连接的玩法很像?SSE就是把原来的HTTP长连接的玩法给标准化了。

Nginx代理SSE请求的一个坑:

嗯,今天同事部署了一个SSE的服务端,他本机测试,内容都是一块一块的刷出来,但是正式环境就永远是等了很久,所有内容再一起出来。

检查了好久,最后发现,他的本地环境是Apache,而服务器是Nginx。Nginx对于flush()的处理,还需要在后端脚本添加额外的Header头才 X-Accel-Buffering: no ,或者在Nginx的配置上面,针对指定请求关闭buffer,Nginx才会立马放行。

小结:

对于iOS的移动页面,如果有对数据响应时间敏感的,可以尝试SSE。

SSE当连接意外断掉之后,会自动重连。

通过SSE,加深了我对XHR的理解,AJAX只是这货的冰山一角。XHR本质就是浏览器上面的curl,熟读HTTP协议,可以用XHR玩出很多花样(对于未支持EventSource的浏览器,Github上有很多基于XHR的降级兼容处理)。

现在还只是初探SSE,还有一些机制后面会深入了解:

  • 例如网关对于这种stream流是如何处理的,2分钟后会不会断掉?
  • SSE有消息ID的约束,我们还有必要在消息内容区域自己再约定一次消息ID吗?
  • EventSource的重连可不可靠?因为同事担心上面提到的网关问题,所以故意在50s左右服务端会主动关闭连接。而此时,EventSource发现连接断掉后,自动又重新发起了连接。

“利用H5的EventSource,小试服务器推送(SSE)”的一个回复

  1. 想从服务器端推送消息到客户端的话,还可以试一下GoEasy推送,它有Restful API 支持多语言,而且针对java他们还特别做了SDK,使用很简单方便。同时它也支持客户端推送。由于它支持websocket 和polling两种连接方式所以兼顾大多数主流浏览器,低版本的IE浏览器也是支持的,个人觉得很不错

发表评论

电子邮件地址不会被公开。 必填项已用*标注