Ajax实现的长轮询不阻塞同一时间内页面的其他Ajax请求(同域请求)
最近要做一个来电的弹屏功能,利用OM 系统的接口,OM系统发送请求到接口程序,分析数据添加到mysql数据库中,然后把最新的数据id 跟今日来电的总的数量存储到memcache 中。弹屏程序根据读取的memcache 中的数据 比对,比较是不是有新的请求到来。中间遇到问题是:前台在轮询等待数据的时候,页面中的其他请求被阻塞,查了好多资料,包括 apache 的mpm 模式,都没有找到原因。后来 在论坛里边查到原因:如下
实际上是不能并发访问同一个站点使用了session的页面,因为访问A页面时,session被锁住了,B页面要等A页面结束释放锁才能被执行。解决方 法就是不用session,或者session使用后立刻释放(php 使用session_write_close释放session锁)。
以下是我的具体操作的代码:
js:
function load_cdr_data() {
//获取现在的数据
var url='__MODULE__/Cdrmanage/get_cdr_info?id=';
var cdr_count = $('input[name="cdr_count"]').val();
$.ajax({
type: "POST",
dataType: "json",
async: true,
url: '__MODULE__/Cdrmanage/get_newcdr',
timeout: 80000, //ajax请求超时时间80秒
data: {
time: 80,
count: cdr_count,
}, //40秒后无论结果服务器都返回数据
success: function (data) {
//从服务器得到数据,显示数据并继续查询
if (data.status == "10") {
var title='您刚才拨打的电话。';
url=url+data.cdr_id;
open_no_savebtn_dialog('',url,title);
$('input[name="cdr_count"]').val(data.count);
new_load_cdr_data();
}
//未从服务器得到数据,继续查询 超时间了
if (data.status == "20") {
new_load_cdr_data();
}
},
//Ajax请求超时,继续查询
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (textStatus == "timeout") {
new_load_cdr_data();
}
}
});
}
php 代码实现
/**
* 获取cdr 数据信息 初次加载的时候不返回数据 初次的时候count数据为0
* @access public
*/
public function get_newcdr() {
import('Vendor.phpmemcache.Memcachemanage');
$precount = I('post.count');
$time = I('post.time');
$user_id = session('USER_ID');
$host = '127.0.0.1';
$port = '11211';
$expire = '0';
$memcache_prefix = '';
$mem = new \Memcachemanage($host, $port, $expire, $memcache_prefix);
if (empty($time)) {
set_time_limit(0);
}
//无限请求超时时间 永久执行直到程序结束
//session解锁 这个地方查了好久才看到
//为了安全考虑(避免单个用户并发请求导致的session数据错乱),
//PHP采用排它锁来互斥的访问session数据
//(不管你是用session文件还是memcache存session),
//也就是说开启了session后,单个用户只能串行的访问这个站点,
//并发的请求只有一个会被立刻响应,其它都会被阻塞
session_write_close(); //session被占用导致的 排他锁机制
$i = 0;
while (true) {
$i++;
//若得到数据则马上返回数据给客服端,并结束本次请求
//操作memcache 获取数据
$cdr_info = $mem->get($user_id);
$max_id = $cdr_info['max_id'];
$count = $cdr_info['count'];
if ($count > $precount) {
//可以返回一个url 然后弹出窗体实现
$return = array('status' => '10', 'cdr_id' => $max_id, 'count' => $count);
exit(json_encode($return));
}
if ($i == $time) {
//防止程序一直执行 返回数据到前台 前台关闭之后 停止请求
$return = array('status' => "20");
exit(json_encode($return));
}
usleep(500000); //1秒 表示一秒钟判断一下数据状态
}
}
Ajax实现的长轮询不阻塞同一时间内页面的其他Ajax请求(同域请求)的更多相关文章
- 网页实时聊天之js和jQuery实现ajax长轮询
众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的长时间联系,从而源源不段地获取信息. 一直以来的方式 ...
- [转]网页实时聊天之js和jQuery实现ajax长轮询 PHP
网页实时聊天之js和jQuery实现ajax长轮询 众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的 ...
- 用.NET MVC实现长轮询,与jQuery.AJAX即时双向通信
两周前用长轮询做了一个Chat,并移植到了Azure,还写了篇博客http://www.cnblogs.com/indream/p/3187540.html,让大家帮忙测试. 首先感谢300位注册用户 ...
- Gevent的长轮询实现方法详解
长轮询 1.浏览网页时,浏览器会传HTTP 请求到服务器,服务器会根据请求将网页的内容传给浏览器,但是在很多的情况下,使用者会需要看到最新的即时性资讯,例如观看股票市场行情,而在以前只能靠着重新载入网 ...
- 实现Comet(服务器推送)的两种方式:长轮询和http流
Comet 是一种高级的Ajax技术,实现了服务器向页面实时推送数据的技术,应用场景有体育比赛比分和股票报价等. 实现Comet有两种方式:长轮询与http流 长轮询是短轮询的翻版,短轮询的方式是:页 ...
- 基于Ajax的长轮询(long-polling)方式
如 图 1 所示,AJAX 的出现使得 JavaScript 可以调用 XMLHttpRequest 对象发出 HTTP 请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML 页面 ...
- php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室)
php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室) 一.总结 1.ajax长轮询和websocket都可以时间网络聊天室 ...
- Js和Jquery实现ajax长轮询
众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的长时间联系,从而源源不段地获取信息. 一直以来的方式 ...
- 分享一个基于长连接+长轮询+原生的JS及AJAX实现的多人在线即时交流聊天室
实现网页版的在线聊天室的方法有很多,在没有来到HTML5之前,常见的有:定时轮询.长连接+长轮询.基于第三方插件(如FLASH的Socket),而如果是HTML5,则比较简单,可以直接使用WebSoc ...
随机推荐
- 爬虫技术实战 | WooYun知识库
爬虫技术实战 | WooYun知识库 爬虫技术实战 大数据分析与机器学习领域Python兵器谱-大数据邦-微头条(wtoutiao.com) 大数据分析与机器学习领域Python兵器谱
- [置顶] Java启动命令大观
Java启动命令是所有java应用程序的入口,通过它来启动Java运行时环境,并加载相关的class.不过由于IDE的盛行,我们Java程序员中的大多数的并不是非常的了解Java启动命令.本文希望做一 ...
- ArrayList and LinkedList
ArrayList and LinkedList List代表一种线性表的数据结构,ArrayList则是一种顺序存储的线性表.ArrayList底层采用数组来保存每个集合元素,LinkedList则 ...
- CentOS6.5解决中文乱码与设置字符集
[ CleverCode发表在csdn博客中的原创作品,请勿转载,原创地址:http://blog.csdn.net/clevercode/article/details/46377577] 1)说明 ...
- C程序内存管理
C程序的内存管理 熟悉Java语言的肯定知道,Java中内存管理是由虚拟机帮助我们完毕的,在C/C++中可不是这样,程序猿须要自己去分配和回收内存空间.本文记录了C程序可运行文件的存储结构.在内存中的 ...
- 习WebSocket一(WebSocket初识)[转]
http://www.cnblogs.com/wgp13x/p/3812579.html Java EE 7 去年刚刚发布了JSR356规范,使得WebSocket的Java API得到了统一,Tom ...
- 关于MySQL的各种总结
https://blog.atime.me/note/mysql-summary.html 总结使用MySQL过程中遇到的各种问题和一些有用的资源,配置等等.将之前的若干篇零散的文章汇总到一起,备忘. ...
- iOS--RunLoop原理介绍
什么是RunLoop RunLoop从字面上看是运行循环的意思,这一点也不错,它确实就是一个循环的概念,或者准确的说是线程中的循环. 本文一开始就提到有些程序是一个圈,这个圈本质上就是这里的所谓的Ru ...
- 第四篇:python基础之dict、set及字符
python基础之dict.set及字符 python基础之dict.set及字符串处理 本节内容 字典介绍及内置方法 集合介绍 字符串处理 1.字典介绍及内置方法 字典是python中唯一的映射 ...
- JS中的事件绑定,事件捕获,事件冒泡以及事件委托,兼容IE
转载请注明出处:http://www.cnblogs.com/zhangmingze/p/4864367.html ● 事件分为三个阶段: 事件捕获 --> 事件目标 --> ...