由于有一个需求,需要把一些统计数据实时显示在web上,不需要考虑浏览器兼容性。找了一圈之后,有客户端轮询式的ajax,有高大上的websocket,html5的SSE(SERVER-SENT EVENTS 服务端发送事件)感觉实现起来比较简单。
首先找到了这篇文章《PUSHING UPDATES TO THE WEB PAGE WITH HTML5 SERVER-SENT EVENTS》,根着它做,准备好两个文件:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="serverData">Here is where the server sent data will appear</div>
<script type="text/javascript">
//check for browser support
if (typeof (EventSource) !== "undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("send_sse.php");
//detect message receipt
eSource.onmessage = function (event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
};
} else {
document.getElementById("serverData").innerHTML = "Whoops! Your browser doesn't receive server-sent events.";
}
</script>
</body>
</html>
send_sse.php
<?php
//streaming code
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
//generate random number for demonstration
$new_data = rand(0, 1000);
//echo the new number
echo "data: New random number: $new_data\n\n";
flush();
?>
放到支持PHP的apache2服务器上,用chrome和firefox访问得到结果是,每隔一个固定的时间,大概4秒吧,会更新显示一次随机数,查看F12如下图所示。
什么?!说好的由服务端主动推送数据呢?
上面的图看起来仍旧是客户端(浏览器)每隔一定的时间去刷新服务端数据啊!而且这个时间间隔还是固定的没有任何地方可以设置,离介绍说的服务端有数据就推送给浏览器然后由浏览器负责显示相去甚远。
事情应该没有那么简单的。再找文章,这次找到这篇文章《html5之sse服务器发送事件EventSource介绍》
根据文章,修改了服务端代码如下:
send_sse.php
<?php
//streaming code
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(1){
//generate random number for demonstration
$new_data = rand(0, 1000);
//echo the new number
echo "data: New random number: $new_data\n\n";
ob_flush();
flush();
$delay = rand(1,10);
usleep($delay * 100000);//随机延迟100毫秒到1秒
}
?>
刷新index.html页面,这次对了,数据更新有时快有时慢(在100毫秒和1秒之间),而且客户端不会一次一次去连接服务端,而是保持着一个长时间的连接,F12如下图所示: