实现目标
对数据库的数据更新进行监测,如果更新了数据就将数据全部显示出来,没有更新,则一直监测。
比如有一个服务端(浏览器),有很多客户端(浏览器),客户端提交了数据,服务端想要在不刷新浏览器的情况下知道是不是有数据提交了,就可以通过长连接实现了,如投票系统等都可以用长连接来实现。在这里就不介绍长连接和短连接以及相关的技术—websocket了。
实现原理
实现原理很简单,就是通过ajax嵌套,ajax去POST请求,到控制器里面查询数据表的记录数是否更改了,如果更改了就将数据ajajReturn回来,然后再去ajax Post请求。如此循环。
测试实现
js
//开始长连接,轮询查询数据库
function getData(msg){
if(msg == undefined){
msg = '';
}
$.ajax({
url: localhostPaht +'/Home/Cashier/getAllMsgTradeCode/',
type: 'POST',
dataType: 'json',
data:{
'msg':msg
},
success: function(data){
if(data){
console.log(data);
}
else {
console.log(data.length);
}
getData('');
},
error: function(){
alert("获取MSG交易编号失败");
}
});
}
//初始化消息列表数据
getData("init");
控制器:
public function getAllMsgCount(){
$sql = "select count(*) as count from t_trade_detail_temp;";
$res = M()->query($sql);
$count = $res[0]['count'];
return $count;
}
public function getAllMsgTradeCode(){
$oldCount = $this->getAllMsgCount();
$sql = "select trade_code from t_trade_detail_temp;";
$data = M()->query($sql);
if($_POST['msg'] == "init"){
$this->ajaxReturn($data);
exit;
}
while(true){
set_time_limit(0);
$newCount = $this->getAllMsgCount();
if($newCount > $oldCount){
$data = M()->query($sql);
$this->ajaxReturn($data);
break;
}
usleep(1000);
}
}
首先第一次调用getData(‘init’);获取数据表初始数据,然后在ajax嵌套中对数据库进行监测,当数据库数据更新时,则会在控制器中跳出while循环,返回包括了更新的所有数据。然后又重新进入监测。
浏览器控制台打印的调试数据(客户端数据更新是通过直接在数据表中插入数据来模拟的):
注意:因为是用ajax POST请求方式,且是嵌套的,所以打开页面后就不能够实现刷新了,除非关闭浏览器重新打开,这也是不好的一点。不过采用websocket就不会出现这种缺点了。
解决刷新的问题:在控制器的while循环中,可以设置一个标识,每隔一定的时间就算数据表的数据没有更新也返回一个空的数据回来,这样就不是一直在等待,浏览器也就可以刷新了。
while(true){
set_time_limit(0);
$time_count++;
$newCount = $this->getAllMsgCount();
if($newCount != $oldCount){
$data = M()->query($sql);
$this->ajaxReturn($data);
break;
}
usleep(1000);
//一定的时间后没有数据变化也跳出
if($time_count >= 800){
$data = "";
$this->ajaxReturn($data);
break;
}
}
当页面既有同步ajax,又有异步ajax时
这个时候刷新的时间跟time_count有关,time_count越小,刷新时间越短,但是随之而来的就是服务器的CPU消耗增大。