介绍
之前参与项目里,见到过有人用ajax长轮询来做实时数据推送。但是这样做有一个弊端就是会建立很多TCP连接,这样会给系统带来比较大的IO负担。
有没有一种方式,我们只进行一次TCP连接,在这一次TCP连接中,服务器不断给客户端吐数据。下面我们就来介绍一下comet推送方式:
comet推送方式
我们用php来做服务端
<?php
header("Content-type:appliacation/json;charset=utf-8");
header("Cache-Control:max-age=0"); // 让前端接收没有缓冲,因为我们要实时获取数据
// 我们用一种方式,让它连上之后不释放
$i=0;
while($i<9){
$i++;
$radom = rand(1,999);
sleep(1);
echo $radom;
echo "<br>";
ob_flush(); // 把当前资源释放掉
flush(); // 拿到释放掉的资源,吐浏览器
// 一直让它输出,而且是一个流式输出
}
?>
js怎样捕捉一直在发送阶段
<script>
var getXmlHttpRequest = function(){
if(window.XMLHttpRequest){
return new XMLHttpRequest();
}
else if(window.ActiveXObject){
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
var xhr = getXmlHttpRequest();
xhr.onreadystatechange = function (){
console.log(xhr.readyState);
// 检测readyState为3的时候,我们就能把responseText输出出来
// 而且每次一都能把上次全部内容都打印出来
if(xhr.readyState ===3 &&xhr.status === 200){
console.log(xhr.responseText);
}
}
xhr.open("get","data.php",true);
xhr.send("");
</script>
那我们能不能用普通的ajax来实现呢,也是可以的
js用普通ajax去请求
<script>
function conn(){
$.ajax({
url: 'data.php',
dataType: 'json',
success: function(data){
console.log(data);
conn();
}
})
}
conn();
</script>
服务端我们不去断掉连接
<?php
header("Content-type:appliacation/json;charset=utf-8");
header("Cache-Control:max-age=0");
sleep(1);
$res = array('success'=>'ok','test'=>'我是测试文本');
echo json_encode($res);
?>
或者我们用下面这种方式,用一个while循环,我们可以通过前端给来的参数去判断执行过少次。
<?php
header("Content-type:appliacation/json;charset=utf-8");
header("Cache-Control:max-age=0");
while(true){
sleep(1);
$res = array('success'=>'ok','test'=>'我是测试文本');
echo json_encode($res);
exit(); // 切记要退出,不然前端拿不到数据
}
?>
因为只要不断掉,我们再去请求还是连接的上一次请求,只不过这是用前端实现了轮询效果,刚才我们用后端flush()来实现的这件事
网友评论