JavaScript与jQuery实现AJAX长轮询实时聊天
本文详解如何利用JavaScript原生及jQuery库实现基于AJAX的长轮询技术,构建网页实时聊天功能。通过解析HTTP无状态特性,对比长连接、Flash Socket、普通轮询及WebSocket等方案,重点阐述长轮询在减少无效请求方面的优势。内容涵盖MySQL数据库设计、PHP后端无限等待逻辑、以及前端的异步请求处理与POST发送实现,提供完整代码思路与注意事项。
介绍
HTTP协议特点与实时通信挑战
HTTP协议作为应用层面向对象的协议,具备五个显著特征:
1、支持客户/服务器模式;
2、简单快速;
3、灵活;
4、无连接;
5、无状态。
由于每次HTTP请求都是独立事件,前后请求互不关联,因此在开发网页实时聊天应用时,核心挑战在于如何维持与服务器端的长期连接,以确保持续获取信息。
常见实时通信方案对比
目前常见的解决方案主要包括以下几种:
1、长连接:服务器端保持连接不断开,例如PHP中使用ob系列函数持续读取输出,但这种方式对服务器资源消耗极大。
2、Flash Socket:利用Flash的AS3语言创建Socket服务器来处理信息交互。
3、普通轮询:即客户端不停地发送查询消息,一旦有新消息立即更新,但会产生大量无效的重复请求。
4、长轮询:这是轮询技术的升级版,需要服务器端进行配合支持。
5、WebSocket:HTML5提供的通信功能,通过建立专用接口ws协议进行通讯,但需考虑浏览器兼容性问题。
本文将总结使用JavaScript和jQuery两种方式(主要区别在于JS与JQ的实现差异)来实现AJAX长轮询。
长轮询原理与优势
长轮询的核心思想如下:

如图:,通过AJAX发送询问信息,若服务器端暂无信息返回,则进入无限等待状态。得益于AJAX的异步特性,PHP在服务器端的等待过程不会影响页面的其他正常处理。一旦服务器查询到返回信息,便立即返回,AJAX通过回调函数处理该信息,并迅速再次发送新的请求以等待服务器处理。
与传统轮询相比,长轮询在服务器没有返回信息时进入等待状态,从而大幅减少了普通轮询中服务器无数次空回复的情况。可以认为,长轮询使服务器的每次返回更具目的性,避免了盲目返回数据。
服务器端数据库设计与PHP实现
接下来介绍长轮询在服务器端的实现方法:
聊天信息存储方案:
数据库表设计包含字段:信息ID(msgid)、发送人(sender)、接收人(receiver)、信息内容(content)。设置senderRead和receiverRead字段的目的是标记信息是否已被读取,读取后修改该标记,以此区分信息是否已读。
create table msg{
msgid int not null primary key auto_increment,
sender char(16) not null,
receiver char(16) not null,
content text, //信息内容用text类型,存储量可达到65535字符
senderRead tinyint enum(0,1) default 0,
receiverRead tinyint enum(0,1) default 0 //设置一个是否已读的flag标记
}
PHP脚本实现:
脚本的主要职责是处理来自AJAX的每次询问。AJAX每次询问时,脚本查询数据库以查看是否有新信息;如果没有,则使用usleep()函数等待一秒后再次查询,直到有新信息插入数据库并被查询到。脚本返回查询到的数据,并退出无限循环,结束脚本执行。
set_time_limit(0);//设置脚本超时时间为无限,不然在过了超时时间后脚本会自动关闭,轮询失败。
$link=new mysqli("host","user","password","database");
$search="select sender,receiver,content from msg where receiverRead=0 limit 1";//限制每次读出一条数据,便于修改其已读flag
$change="update chat set receiverRead=1 where receiverRead=0 limit 1";
while (true) { //进入无限循环
$res=$link->query($sql); //查询结果
if($res->num_rows!=0){ //当有未读信息时读取信息
$link->query($change);//将信息的已读flag设为1
$msg=$res->fetch_assoc();
$jsonstr=json_encode($msg);//取到信息,将信息用转码为json格式,返回给JS
echo $jsonstr;
break;//输出信息后退出while循环,结束当前脚本
}
usleep(1000);//如果没有信息不会进入if块,但会执行一下等待1秒,防止PHP因循环假死。
}
客户端AJAX请求处理
客户端实现方案:
客户端的主要任务是设置一个AJAX请求函数,每次查询时被调用。当没有信息返回时,服务器端处于搁置状态,当前页面可正常执行;当有信息返回时,函数处理返回的数据,并迅速再次调用此函数发送一次新的请求。
原生JS与jQuery实现代码
使用原生JavaScript实现:
function link(){
var xhr=null;//先设置xhr为空,为了轮询时再次调用函数对xhr重用,引发错误
xhr=new XMLHttpRequest();
xhr.open('GET','serviceback.php',true);//第三个参数一定要设置为true,异步不阻塞,不会影响到后面JS的执行。
xhr.send();
xhr.onreadystatechange=function(){
if (xhr.readyState==4) { 严密也可加使用(xhr.readyState==4 && xhr.status ==200)限定服务器响应码为200时才进行处理。
if(xhr.responseText!=''){
process... //服务器端返回信息,且返回信息不为空,则开始处理返回信息。
}
setTimeout("link()",300);
//递归再次调用link()函数,用setTimeOut()设置延时是因为服务器端进行sql操作时会耗时,当有新信息时,在服务器将要置已读flag为1还未成功时,AJAX可能已经又发出多条查询信息了,会导致一条信息多次返回。
}
};
}
使用jQuery插件实现:
var link={ //jQuery的AJAX执行的配置对象
type:"GET", //设置请求方式,默认为GET,
async:true, //设置是否异步,默认为异步
url:"customback.php",
dataType:"json", //设置期望的返回格式,因服务器返回json格式,这里将数据作为json格式对待
success:function (msg){
process...
setTimeout("link()",300);
} //成功时的回调函数,处理返回数据,并且延时建立新的请求连接
}
$.ajax(link); //执行ajax请求。
]发送功能与消息处理优化
程序功能扩充:
添加发送聊天窗口功能:
新建一个函数来处理AJAX的POST请求,通过AJAX将发信人、每次发送的信息内容、收信人发送到服务器端,并设置一个单独的PHP脚本来处理这些信息,将信息插入数据库。
需要注意的是,使用JS原生实现POST请求发送信息时,必须设置ajax对象的HTTP头,以模拟表单提交的操作:。
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
聊天室消息处理优化:
为了防止每次都查询到全部历史消息,我们对数据库的查询操作进行了调整。设置idflag=0,每次查询后,将idflag设置为查询到的数据的ID。在后续查询时,我们只查询比idflag大的ID,即仅获取新添加进去的信息。
至此,本文内容结束。利用本文提供的示例代码,一个简单的聊天室程序即可搭建完成,感兴趣的读者可以尽快进行实践。
ES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
