demo.html
<div id="box">
<div id="msg"></div>
昵称:<input type="text" id="name" value="xiaocai" /><br />
内容:<textarea id="text">
<input id="chat" type="hidden" value="0" />
lt;div align="center"><input id="btn" type="button" value="OK" /></div>
#box{ width:355px; background-color:#CCC;}
#name{width:100px;}
#text{ width:300px;}
#msg{ width:340px; height:200px; background-color:#EFEFEF; margin:2px; overflow:auto; padding:5px;}
由客户端向服务器端发出请求并打开一个连接。这个连接只有在收到服务器端的数据之后才会关闭。服务器端发送完数据之后,就立即关闭连接。客户端则马上再打开一个新的连接,等待下一次的数据.
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
$(function(){
LongPolling();
$("#btn").click(function(){
if($("#text").val()=="") return false;
$.ajax({
type:"POST",
dataType:"json",
url:"SetMsg.php",
data:{name:$("#name").val(),text:$("#text").val()},
success:function(data){
//
}
});
$("#text").val("");
});
function LongPolling(){
$.ajax({
type:"POST",
dataType:"json",
url:"GetMsg.php",
timeout:80000, //ajax请求超时时间80秒
data:{chat:$("#chat").val()},
success:function(data,textStatus){
//从服务器得到数据,显示数据并继续查询
if(data.success=="1"){
$("#msg").append(data.text);
$("#chat").val(data.chat);
var msg = document.getElementById('msg');
msg.scrollTop = msg.scrollHeight;
LongPolling();
}
//未从服务器得到数据,继续查询
if(data.success=="0"){
LongPolling();
}
},
//请求超时,继续查询
error:function(XMLHttpRequest,textStatus,errorThrown){
if(textStatus=="timeout" || textStatus == 'parsererror'){
LongPolling();
}
}
});
}
});
</script>
GetMsg.php
这是一个死循环,从cache.txt中查询是否有新的数据。有新数据才结束循环并且返回数据给客服端,并结束本次请求。
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
set_time_limit(10);//请求超时时间
$chat=$_POST['chat'];
$return_chat=0;
$html="";
if(!file_exists("cache.txt")){
echo "cache.txt 文件不存在.";exit();
}
while (true){
//sleep(1);
usleep(20000);//0.2秒
//若得到数据则马上返回数据给客服端,并结束本次请求
$handle = fopen("cache.txt","r");
$contents = @fread($handle,filesize ("cache.txt"));
fclose($handle);
$result = json_decode(trim($contents,chr(239).chr(187).chr(191)),true);
if(is_array($result)){
foreach ($result as $key=>$value){
if($value['id']>$chat){
$html.=$value['name']." 说:".$value['text']."<br>";
}
$return_chat=$value['id'];
}
}
if($html!=""){
$arr=array('success'=>"1",'name'=>'xiaocai','text'=>$html,'chat'=>$return_chat);
echo json_encode($arr);
ob_flush();
flush();
exit();
}
}
SetMsg.php
向cache.txt文件中写数据,cache.txt为一个缓存文件。它以单链表的形式存储5条聊天记录。
$id=1;
if(!file_exists("cache.txt")){
echo "cache.txt 文件不存在.";
exit();
}
$handle = fopen("cache.txt","r");
$contents = @fread($handle,filesize ("cache.txt"));
fclose($handle);
$result = json_decode(trim($contents,chr(239).chr(187).chr(191)),true);
if(!empty($result[0]['id'])){
$arr_count=count($result);
$id = (int)$result[0]['id']+$arr_count;
if($arr_count>5){
array_splice($result,0,1);
}
}
$result[]=array('id'=>$id,'name'=>$_POST['name'],'ip'=>$_SERVER['REMOTE_ADDR'],'time'=>date("y-m-d H:i:s"),'text'=>$_POST['text']);
//print_r($result);
$handle = fopen("cache.txt", "w");
fwrite($handle,json_encode($result));
fclose($handle);
效果:
