众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系。所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的长时间联系,从而源源不段地获取信息。

一直以来的方式无非有这么几种:

1、长连接,即服务器端不断开联系,PHP服务器端用ob系列函数来不停的读取输出,但是相当耗费服务器资源。

2、Flash socket,flash的as3语言,创建一个socket服务器用来处理信息。

3、轮询,顾名思义就是不停地发送查询消息,一有新消息立刻更新,但是会有多次无用请求。

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

5、websocket,HTML5的通信功能,建立一个与服务器端的专用接口ws协议来进行通讯,兼容可能成为问题,改天研究一下这个。

这篇博文总结一下用JS和JQ两种方式(其实不同就是js和jq的实现),实现AJAX长轮询。

长轮询的思想:

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

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

长轮询的服务器端实现:

聊天信息存储:

数据库设计为信息ID(msgid),发送人(sender),接收人(receiver),信息内容(content),设置senderRead和receiverRead的目的是标记信息是否已被读取,读取后改变标记,以区别信息是否已经被读取。

create tablemsg{

msgidint not null primary keyauto_increment,

senderchar(16) not null,

receiverchar(16) not null,

contenttext, //信息内容用text类型,存储量可达到65535字符

senderReadtinyint enum(0,1) default 0,

receiverReadtinyint 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请求函数,每次查询时被调用,当没有信息返回时,服务器端被搁置,当前页面正常执行;当有信息返回时,函数处理返回的数据,并迅速再次调用此函数发送一次请求。

用原生JS:

functionlink(){var xhr=null;//先设置xhr为空,为了轮询时再次调用函数对xhr重用,引发错误

xhr=newXMLHttpRequest();

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,即,新添加进去的信息。

这样,一个简单的聊天室程序就做好了。

如果您觉得本博文对您有帮助,您可以推荐或关注我,如果您有什么问题,可以在下方留言讨论,谢谢。

ajax长轮询 java web_网页实时聊天之js和jQuery实现ajax长轮询相关推荐

  1. java+jquery实现长轮询案例_网页实时聊天之js和jQuery实现ajax长轮询

    众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的长时间联系,从而源源不段地获取信息. 一直以来的方式 ...

  2. ajax jq 图片上传请求头_如何使用js或jQuery向Ajax请求添加自定义HTTP头?

    下面是一个使用XHR 2的示例:function xhrToSend(){ // Attempt to creat the XHR2 object var xhr; try{ xhr = new XM ...

  3. 网页实时聊天之PHP如何实现websocket

    网页实时聊天之PHP如何实现websocket 一.总结 一句话总结: 应用 PHP 的 socket 函数库:PHP 的 socket 函数库跟 C 语言的 socket 函数非常类似 PHP 实现 ...

  4. websocket 西部数码php_网页实时聊天之PHP实现websocket

    前言 websocket 作为 HTML5 里一个新的特性一直很受人关注,因为它真的非常酷,打破了 http "请求-响应"的常规思维,实现了服务器向客户端主动推送消息,本文介绍如 ...

  5. jq ajax请求php原声,原生JS与jQuery对AJAX的实现

    原生JS与jQuery对AJAX的实现 一.定义 W3C里这么解释AJAX: AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). ...

  6. ajax长轮询 java web_浅谈Websocket、Ajax轮询和长轮询(long polling)

    浅谈Websocket.Ajax轮询和长轮询(long p0ll) 最近看到了一些介绍Websocket的文章,觉得挺有用,所以在这里将自己的对其三者的理解记录一下. 1.什么是Websocket W ...

  7. 微信小程序 | 基于小程序+Java+WebSocket实现实时聊天功能

    一.文章前言 此文主要实现在小程序内聊天对话功能,使用Java作为后端语言进行支持,界面友好,开发简单. 二.开发流程及工具准备 2.1.注册微信公众平台账号. 2.2.下载安装IntelliJ ID ...

  8. 用signalr实现简单的网页实时聊天

    开发工具与关键技术: js 作者:GuanLW 撰写时间:2022/3/18 第一步:先在vs的NuGet包中下载安装Microsoft.AspNet.SignalR.安装完成后会多以下几个文件 第二 ...

  9. C#——signalr实现简单的网页实时聊天

    1.新建asp.net web应用程序,然后在vs的NuGet包中下载安装Microsoft.AspNet.SignalR 2.右键项目->新建项,选择signalr集线器类,并写入代码,nam ...

最新文章

  1. 32linux下安装mysql5.7_【Linux】【MySQL】安装MySQL,版本5.7
  2. DIY最近准备配一台经济型的电脑,查了一下配置如下,总价2481元,自己也不专业,不知道有没有问题...
  3. Spring(AbstractRoutingDataSource)实现动态数据源切换--转载
  4. XP支持4G以上物理内存的方法
  5. The directory '*' or its parent directory is not owned by the current user
  6. 今日代码(200612)--数据录入(python+mysql)
  7. 前端学习(2538):slice
  8. [TED] Kinect控制的四翼直升机
  9. 毫秒级检测!你见过带GPU加速的树莓派吗?
  10. JavaScript函数作用域
  11. 【Elasticsearch】Elasticsearch的数据类型 (text、keyword、date、object、geo等)
  12. python接口自动化测试二十六:使用pymysql模块链接数据库
  13. Web服务器压力测试工具?
  14. 微信公众号推送天气预报Python
  15. Win10无法打开相机
  16. ​PHP现在不好找工作是真的吗?
  17. 图片处理之thumbnailator和TwelveMonkeys的使用
  18. 最新我爱防红网QQ防红跳转短网址生成源码
  19. 古琴调音频率及音位图(正调F调)
  20. 修改MP4文件二进制内容,实现安卓Camera2旋转录制视频画面功能

热门文章

  1. LeetCode题 - 13 罗马数字转整数
  2. 大数据 自学视频资料,纯分享
  3. pycharm中的数据库可视化
  4. .NET中多线程调试的一个办法
  5. 漫步最优化十六——优化的一般问题
  6. 漫步数理统计五——条件概率与独立(上)
  7. oracle的临时表和With As总结
  8. Java处理微博数据集中的超链接
  9. Java日期型集合排序
  10. 【OpenCV】SIFT原理与源码分析