反向ajax ajax长循环,又叫comet机制,但是我最喜欢的还是叫他反向ajax 反向ajax,顾名思义,就是不是客户端来请求服务器端,而是服务器端请求客户端,这样做的好处是节省了大量以前轮询造成的查询浪费,从而减轻数据库压力和服务器压力 那么如何实现反向ajax呢? 主体 1.在客户端写一个ajax,这个ajax里设置一个过期的时间 timeout,这个过期的时间timeout是用来暂时延长ajax的请求时间的,当这个ajax触发的时候给后台传递一个等于timeout的值。 $.ajax({ type: 'POST', dataType: 'json', url: "do.php", timeout: '20000',//请求超时时间 data: {'time':'2000000','user':user},// 每次请求等待时间 success: function(data){ //逻辑代码 }) 2.在后台的php文件中,我们接受这个timeout,把这个timeout设置为php的搁置时间,这样就算挂起了php处理的这个进程了,这样做是为了和前面ajax的过期时间保持一致,从而一致保持ajax请求这个状态,也就是说在这timeout时间内 ajax的请求和php处理程序进程被挂起了 $time = $_POST['time']; $user = $_POST['user']; if(empty($time)) exit(); set_time_limit(0);// 无限请求超时时间 usleep($time);// 等待时间 重点 3.重点的一步:在一个while循环中处理自己的业务逻辑,然后向前端发送信息,随后退出当前的线程,这样做的意义是沾少量的内存和查最少的数据库 while(true){ if(你自己的判断向客服端发送信息的条件) //send()发送信息后退出线程 exit(); }else{ //无数据发送直接退出线程 exit(); } } 4.前端重要的一步:当你从后端拿出你要的东西时候,将结束上一个长循环,然后挂起下一个长循环ajax,就算你没有拿到数据过了超时时间的话也要结束当前ajax,进行下一个ajax。如果没有数据这个ajax会持续20s,这可比主动每秒访问服务器好多了,这是服务器主动推的,不是客户端每秒轮询的。 success: function(data){ //逻辑代码 } // 未从服务器中获的数据,继续搁置 if(data.success == '0'){ ajax_for_while() } // ajax超时,进入下一个push搁置机制 error:function(XMLHttpRequest,textStatus,errorThrown){ if(textStatus == "timeout"){ ajax_for_while() } } core 客户端发起一个ajax请求,服务端将请求搁置(pending)或者说挂起,直到到了超时时间(timeout)或需要推送时返回;客户端则等待ajax返回后处理数据,再发起下一个ajax请求。 这样的挂起就不是服务器每秒请求ajax的数据库了,这个timeout时间是可以更改的,多少都行。现在是20s,在20s内ajax不会不断请求数据库,或服务器,问他们有没有信息,而是一旦服务器有信息就会主动推送给客户端,而不用客户端每秒都询问了。 完整的代码:前端的 function ajax_for_while() { //AJAX长轮询 $.ajax({ type: 'POST', dataType: 'json', url: "do.php", timeout: '20000',//请求超时时间 data: {'time':'2000000','user':user},// 每次请求等待时间 success: function(data){ if(data.success == '1') ajax_for_while() } // 未从服务器中获的数据 if(data.success == '0'){ ajax_for_while() } }, // ajax超时,进入下一个push搁置机制 error:function(XMLHttpRequest,textStatus,errorThrown){ if(textStatus == "timeout"){ ajax_for_while() } } }); } 后台的 $time = $_POST['time']; $user = $_POST['user']; if(empty($time)) exit(); set_time_limit(0);// 无限请求超时时间 usleep($time);// 等待时间 while(true){ //在数据库中查找相应的最后条未读数据出来 if(empty($user_record_array)){ $arr = array('success'=>'0','error'=>'无新数据'); echo json_encode($arr); exit(); }else{ if($user_record_array['state'] == 0){ $arr = array('success'=>'0','error'=>'有数据'); echo json_encode($arr); exit(); }else{ $arr = array('success'=>'0','error'=>'无新数据'); echo json_encode($arr); exit(); } } } |
|