宝哥软件园

javascript和jQuery实现网页实时聊天的ajax长轮询

编辑:宝哥软件园 来源:互联网 时间:2021-09-08

介绍

众所周知,HTTP协议是属于应用层的面向对象协议。HTTP协议有五个特点:

1.支持客户端/服务器模式;

2.简单快捷;

3.灵活性;

4.没有联系;

5.无状态。

因此,每个请求都是一个单独的事件,前后没有联系。因此,我们在解决网页上的实时聊天时,遇到了一个问题,那就是如何保证与服务器的长期联系,从而不断获取信息。

只有几种方法:

1.长连接,即服务器不停止联系,PHP服务器使用ob系列函数不断读取输出,但是消耗服务器资源。

2.flash socket作为flash的3种语言,创建了一个用于处理信息的socket服务器。

3.轮询,顾名思义就是不断发送查询消息,一有新消息就更新,但是会有很多无用的请求。

4.长轮询是轮询的升级版,需要服务器的配合。

5、websocket、HTML5通信功能,建立特殊接口ws协议与服务器进行通信,兼容性可能会成为问题。

这篇博文总结了js和jq对AJAX长轮询的实现(实际上不同的是JS和JQ的实现)。

长轮询的想法:

如图:用AJAX发送查询信息,服务器在没有信息返回时进入无限等待。由于AJAX的异步特性,PHP在服务器端等待,不会影响页面的正常处理。一旦服务器查询到返回的信息,服务器就返回信息,AJAX使用回调函数来处理这些信息,同时又快速再次发送请求等待服务器处理。

与传统轮询相比,长轮询在服务器没有返回信息时进入等待状态,减少了普通轮询服务器的大量空回复。可以认为长轮询使服务器每次返回更有目的性,而不是盲目返回。

长轮询的服务器端实现;

聊天信息存储:

数据库设计为信息标识(msgid)、发送者、接收者和信息内容。设置senderRead和receiverRead的目的是为了标记信息是否被读取,读取后改变标记来区分信息是否被读取。

创建表msg {msgid int不为null主键auto _ increment,发送方字符(16)不为null,接收方字符(16)不为null,内容文本,//信息内容为文本类型。内存容量可达65535个字符:发送方读取tinyint enum (0,1) default0,接收方读取tinyint enum (0,1)default 0//如果已读取则设置标志标志}PHP脚本:

该脚本的主要目的是处理来自ajax的每个查询。ajax查询数据库以查看是否有任何新信息。如果没有,只需使用usleep()函数等待一秒钟,然后再次查询,直到新信息被插入数据库并被找到。脚本返回查询的数据,退出无限循环并结束脚本。

set _ time _ limit(0);//将脚本超时设置为无穷大,否则超时后脚本会自动关闭,轮询会失败。$ link=new MySQL(' host ',' user ',' password ',' database ');$search='选择发件人、收件人、来自msg的内容,其中receiverRead=0限制1 ';//限制一次读取一条数据,以便修改其读取标志$ change=' update chat set receiver read=1其中receiver read=0限制1 ';While (true) {//输入无限循环$ RES=$ link-query($ SQL);//查询结果if($res-num_rows!=0){ //有未读信息时读取信息$ link-query($ change);//将信息的读取标志设置为1 $ msg=$ RES-fetch _ assoc();$ JSON str=JSON _ encode($ msg);//获取信息,转码为json格式,返回JS echo $ jsonstr打破;//输出信息后退出while循环,结束当前脚本} usleep(1000);//如果没有信息,不会进入if块,但会执行并等待1秒,防止PHP因循环而挂起。}客户端实现:

客户端的主要任务是设置一个ajax请求函数,每次查询时都会调用这个函数。当没有信息返回时,服务器被搁置,当前页面正常执行;当信息返回时,函数处理返回的数据,并快速再次调用该函数发送请求。

使用本机JS:

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。ready state==4){也可以使用严格性(xhr。readystate==4xhr。状态==200)。只有当服务器响应代码为200时,才能进行处理。if(xhr.responseText!=''){流程.//如果服务器返回信息,并且返回的信息不是空的,它将开始处理返回的信息。} setTimeout('(link()',300);//再次递归调用link()函数,使用setTimeOut()设置延迟,因为服务器执行sql操作需要时间。当有新的信息时,AJAX可能已经在服务器即将将read标志设置为1时发出了多条查询消息,这可能会导致一条消息多次返回。} };}用jQuery插件实现:

Var link={ //jQuery的AJAX执行配置对象类型:' GET '。//设置请求模式,默认为get和async3360 true。//设置是否异步,默认为异步URL 3360‘customback . PHP’和数据类型:‘JSON’。//设置期望的返回格式,因为服务器返回json格式,这里,将数据视为json格式:success 3360 function(msg){ process.settimeout ('link()',300);}//回调函数成功时,处理返回的数据,并延迟建立新的请求连接}$。ajax(链接);//执行ajax请求。]程序扩展:

添加发送聊天窗口:

创建一个新的函数来处理ajax的POST请求,用ajax将发送者、每次发送的信息和接收者发送到服务器,并设置一个单独的PHP脚本来处理信息并将其插入数据库。

需要注意的是,在使用JS原生实现POST请求发送信息时,应该设置ajax对象的HTTP头来模拟表单提交的操作:

xhr . setrequestheader(' Content-type ',' application/x-www-form-URL encoded ');

聊天室消息处理:

为了防止每次都查询所有信息,我们通过设置idflag=0来更改数据库的查询操作。每次查询后,我们将idflag设置为查询数据的id。查询时,我们查询大于idflag的ID,也就是新增加的信息。

好了,这篇文章到此结束。一个简单的聊天室程序将使用本文的示例代码来完成,感兴趣的可以快速练习。

更多资讯
游戏推荐
更多+