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);