Js和Jquery实现ajax长轮询
众所周知,HTTP协议是⽆状态的,所以⼀次的请求都是⼀个单独的事件,和前后都没有联系。所以我们在解决⽹页实时聊天时就遇到⼀个问题,如何保证与服务器的长时间联系,从⽽源源不段地获取信息。
⼀直以来的⽅式⽆⾮有这么⼏种:
1、长连接,即服务器端不断开联系,PHP服务器端⽤ob系列函数来不停的读取输出,但是相当耗费服务器资源。
2、Flash socket,flash的as3语⾔,创建⼀个socket服务器⽤来处理信息。
3、轮询,顾名思义就是不停地发送查询消息,⼀有新消息⽴刻更新,但是会有多次⽆⽤请求。
4、长轮询,是轮询的升级版,需要服务器端的配合。
5、websocket,HTML5的通信功能,建⽴⼀个与服务器端的专⽤接⼝ws协议来进⾏通讯,兼容可能成为问题,改天研究⼀下这个。
如图:⽤AJAX发送询问信息,服务器在没有信息要返回的时候进⼊⽆限等待。由于AJAX异步的特性,PHP在服务器端执⾏等待不会影响到页⾯的正常处理。⼀旦服务器查询到返回信息,服务器返回信息,AJAX⽤回调函数处理这条信息,同时迅速再次发送⼀个请求等待服务器处理。
与传统轮询相⽐,长轮询在服务器没的返回信息的时候进⼊等待,减少了普通轮询服务器⽆数次的空回复。可以这样认为,长轮询使服务器每次的返回更有⽬的性,⽽不是盲⽬返回。
长轮询的服务器端实现:
聊天信息存储:
数据库设计为信息ID(msgid),发送⼈(sender),接收⼈(receiver),信息内容(content),设置senderRe
ad和receiverRead的⽬的是标记信息是否已被读取,读取后改变标记,以区别信息是否已经被读取。
CREATE TABLE `msg` (
`msgid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sender` char(16) NOT NULL,
`receiver` char(16) NOT NULL,
`content` text,
`senderRead` tinyint(1) DEFAULT '0',
`receiverRead` tinyint(1) DEFAULT '0',
PRIMARY KEY (`msgid`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
PHP脚本:
脚本的主要⽬的是处理来⾃ajax的每次询问,ajax每次询问就查询⼀下数据库,看有没有新的信息,如果没有,刚⽤usleep()函数等待⼀秒后再次查询,直到有新信息插⼊数据库并被查到,脚本返回查询到的数据,并退出⽆限循环,结束脚本。
<?php
set_time_limit(0);//设置脚本超时时间为⽆限,不然在过了超时时间后脚本会⾃动关闭,轮询失败。
$link=new mysqli("127.0.0.1","root","root","test");
$search="select sender,receiver,content from msg where receiverRead=0 limit 1";//限制每次读出⼀条数据,便于修改其已读flag
$change="update msg set receiverRead=1 where receiverRead=0 limit 1";
while (true) {//进⼊⽆限循环
$res = null;
$res=$link->query($search);
if($res->num_rows!=0){
$link->query($change);
$msg=$res->fetch_assoc();
$jsonstr=json_encode($msg);
echo $jsonstr;
break;
}
usleep(1000);//如果没有信息不会进⼊if块,但会执⾏⼀下等待1秒,防⽌PHP因循环假死。
}
>
客户端实现:
客户端的主要任务是设置⼀个ajax请求函数,每次查询时被调⽤,当没有信息返回时,服务器端被搁置,当前页⾯正常执⾏;当有信息返回时,函数处理返回的数据,并迅速再次调⽤此函数发送⼀次请求。
⽤原⽣JS:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> </title>
</head>
<body>
</body>
原生js和js的区别<script>
function link(){
var xhr=null;//先设置xhr为空,为了轮询时再次调⽤函数对xhr重⽤,引发错误
xhr=new XMLHttpRequest();
xhr.open('GET','server.php',true);//第三个参数⼀定要设置为true,异步不阻塞,不会影响到后⾯JS的执⾏。
xhr.send();
adyState==4 && xhr.status==200){
var obj = JSON.sponseText)
console.log('发送⼈:'+obj.sender+'接收⼈:'+iver+'内容:'+t)
setTimeout(function(){link()},3000)
}
};
}
link();
</script>
</html>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论