html5的服务器端推送事件Server-Sent Events进阶
发布于 作者:苏南大叔 来源:程序如此灵动~在前一篇文章中,苏南大叔给大家讲解了server-sent的最基本用法,在本篇文章之中,我们将学习到server-sent的更高级用法。在具体讲解之前,苏南大叔先透露一下相关内容。那就是,server-sent的接口格式是本篇文章的重点。我们来详细学习一下吧。
接口格式
首先,这个接口无论用什么语言编写。都必须发出名为 “Content-Type” 的 header 头,内容是 “text/event-stream”,而 “Cache-Control: no-cache” 这个 header 头并非必须的,而仅仅是个推荐项目。
下面用php来模拟一下这段内容:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// data...
接口结束输出
江湖流传,接口的结尾不能使用response.end之类的语句,换到php里面就是不能使用exit的语句,必须改成flush,这个函数的说明见这里:http://doc.php.sh/zh/function.flush.html 。不过,事实证明,这个接口的代码,用什么结尾都ok。所以,对于php来说,flush函数并非必须的。
// data...
// flush();
接口是多次“请求”的
接口是定期多次“请求”的,所以接口里面并不存在while(true)。网路上的部分教程里面,会写while(true)来保持接口。这个,可能是个错误的理解。
//while(true){
// data...
//}
接口的请求间隔是服务器端设置的
接口里面使用 retry 参数来控制请求的间隔,单位是毫秒。如果没有设置 retry 输出的话,据苏南大叔观察,在chrome里面的时间间隔是3秒。
// data...
echo "retry: 50000\n"; //5秒
接口里面可以输出多个data
data字段可以一次性输出,也可以分成多行输出,注意用其中的换行符。每个data的结尾需要两个换行符。
// header...
echo "data: {\n";
echo "data: \"foo\": \"bar\"\n";
echo "data: }\n\n";
也可以这样:
// header...
echo "data: {\"foo\": \"bar\"}\n\n";
接口里面可以自定义特殊事件
默认的事件在客户端是用 “message” 来接收的,但是事实上,这个事件名称是可以自定义的。
下面是客户端的代码。
// init ...
s.addEventListener("MyEvent", function (e) {
console.log(e.data);
});
服务器端代码
// header...
echo "event: MyEvent\n";
echo "data: hi from server\n\n";
服务器端的输出可以触发多个输出
下面的输出,可以同时触发客户端的三个事件:两个普通事件,一个自定义事件。
// header
echo "data: 第一个默认事件\n\n";
echo "data: 第二个默认事件\n\n";
echo "event: MyEvent\n";
echo "data: 第三个自定义事件\n\n";
事件可以自定义id
服务器端使用 id 输出,但是客户端确实使用 lastEventId 来识别,这个是有些奇怪。
客户端:
s.onmessage = function (e) {
//console.log(e);
console.log(e.lastEventId);
};
服务器端:
echo "id: msg1\n";
echo "data: 识别id\n\n";
总结
接口必须输出特定content-type的header,可以输出多个事件。每个事件必须输出data,用2个换行符结尾。每个data可以配一个id和一个event。整体可以用retry来控制频率。但是一个接口只会有一个请求频率,所以说生效的retry只有一个。
本例子中,苏南大叔是以php为例子的,在其他语言中大同小异。将来如果有机会,苏南大叔会以其他语言作为接口范例,继续讲解这个server-sent事件。欢迎大家关注:https://newsn.net/tag/server-sent/ 。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。