众所周知,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),设置senderRead和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>
<script>
function link(){ var xhr=null;//先设置xhr为空,为了轮询时再次调用函数对xhr重用,引发错误 xhr=new XMLHttpRequest(); xhr.open('GET','server.php',true);//第三个参数一定要设置为true,异步不阻塞,不会影响到后面JS的执行。 xhr.send(); xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200){ var obj = JSON.parse(xhr.responseText) console.log('发送人:'+obj.sender+'接收人:'+obj.receiver+'内容:'+obj.content) setTimeout(function(){link()},3000)
}
};
}
link();
</script>
</html>
Js和Jquery实现ajax长轮询的更多相关文章
-
[转]网页实时聊天之js和jQuery实现ajax长轮询 PHP
网页实时聊天之js和jQuery实现ajax长轮询 众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的 ...
-
网页实时聊天之js和jQuery实现ajax长轮询
众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的长时间联系,从而源源不段地获取信息. 一直以来的方式 ...
-
php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室)
php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室) 一.总结 1.ajax长轮询和websocket都可以时间网络聊天室 ...
-
Comet 反Ajax: jQuery与PHP实现Ajax长轮询
原文地址(http://justcode.ikeepstudying.com/2016/08/comet-%E5%8F%8Dajax-%E5%9F%BA%E4%BA%8Ejquery%E4%B8%8E ...
-
Ajax 长轮询
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求. 优点:在无消息的情况下不会频繁的请求. 缺 ...
-
用大白话揭开Ajax长轮询(long polling)的神秘面纱
在看这篇Ajax长轮询之前可以先看看Ajax轮询技术(没有长),有助于理解: Ajax长轮询属于Ajax轮询的升级版,在客户端和服务端都进行了一些改造,使得消耗更低,速度更快. "不间断的通 ...
-
ajax长轮询 (转)
javaWeb项目中需要一个实时提醒的功能,也就是某人做了某一操作,可以立即提醒到当前在线的用户 最开始想在用户做了操作后,储存一个状态到数据库中然后用每隔几秒用ajax去请求后台查询数据库来确定是否 ...
-
基于jquery,php实现AJAX长轮询(LongPoll),类似推送机制
HTTP是无状态.单向的协议,用户只能够通过客服端向服务器发送请求并由服务器处理发回一个响应.若要实现聊天室.WEBQQ.在线客服.邮箱等这些即时通讯的应用,就要用到“ 服务器推送技术(Comet)” ...
-
Ajax长轮询(LongPoll)
1)HTML HTTP是无状态.单向的协议,用户只能够通过客服端向服务器发送请求并由服务器处理发回一个响应.若要实现聊天室.WEBQQ.在线客服.邮箱等这些即时通讯的应用,就要用到“ 服务器推送技术( ...
随机推荐
-
物料分类账 [COML] PART 1 - 概览
物料分类账 [COML] PART 1 - 概览 一).原理 1). •实际成本/物料分类帐是产品成本控制模块的一个子模块,产品成本控制包括三个子模块,产品成本计划,成本对象控制,实际成本/物料分类帐 ...
-
WIN7系统自带截图工具SnippingTool
在无网络的情况下,无QQ情况下,如何截图?以及如何设置快捷键? 方法 首先,我们在“开始”菜单最上面找到它,如图: 找不到也没关系 C:\Windows\system32\SnippingTool.e ...
-
LED_9261在linux2.6.30中tick_led的实现
在linux2.6.30内核中,内核也提供了相关的平台驱动来操作gpio或LED,但更简便的方法是直接操作GPIO来控制led. 网上一博文中介绍直接封装led_on和led_off()函数直接调用即 ...
-
黄聪:360浏览器、Chrome调试(debugger)JS总是进入paused in debugger状态
在通过Chrome浏览器进行web前端开发时,我们会经常用到Chrome自带的debugger工具,但是经常按完快捷键(F12)后,页面会进入paused in debugger状态,需要点击右上角的 ...
-
线程(Thread)
package cn.gouzao.demo3; public class ThreadDemo extends Thread{ public void run(){ for(int i=0;i< ...
-
【转载】 python-星号变量的特殊用法
原文链接:https://www.qingsword.com/qing/python-12.html 引言 在Python中,星号除了用于乘法数值运算和幂运算外,还有一种特殊的用法"在变量前 ...
-
HttpClient配置SSL绕过https证书
https://blog.csdn.net/irokay/article/details/78801307 HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的 ...
-
hibernate基础配置
数据库表名和类名 一致 注解:可写可不写: XML:可写可不写: <class name="Student"> 不一致 注解: public class Teache ...
-
线上环境HBASE-1.2.0出现oldWALs无法自动回收情况;
正常情况下,hmaster会定期清理oldWALs文件夹,一般该文件大小也就几百兆,但是我们线上 环境出现了该文件没有自动回收情况,如图: 该目录占用hdfs空间多达7.6T,浪费空间: 后来经过多番 ...
-
STM32探秘 之FSMC
源:STM32探秘 之FSMC STM32 FSMC总线深入研究