最近要做一个来电的弹屏功能,利用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秒 表示一秒钟判断一下数据状态
}
}

最新文章

  1. 【转】visio中关于shape属性的修改和读取
  2. Linux系统的压缩技术
  3. Struts2框架之-注解开发
  4. C#常用字符串加解密方法封装
  5. iOS 微信支付
  6. JavaScript的执行上下文
  7. yii 10.16
  8. Hibernate与 MyBatis的比较
  9. vim 全局替换命令
  10. 【性能诊断】三、单功能场景的性能分析(RedGate Profiler)
  11. HDU 5858 Hard problem
  12. Hello World for U (20)
  13. 一篇关于学C++的感想(拿来与大家分享)
  14. invoke-command
  15. 未知的生成错误 因为没有预加载,所以无法解析程序集 GalaSoft.MvvmLight
  16. iOS开发学习路径的一些建议
  17. 利用jquery encoder解决XSS脚本注入所产生的问题
  18. python学习之类的反射
  19. Nim函数调用的几种形式
  20. array_filter与array_map

热门文章

  1. spring 学习的开源项目
  2. XMPPFrameWork IOS 开发(六)聊天室
  3. Huffman树及其应用
  4. ng-repeat 遍历同值数组导致的报错
  5. JS方法在iframe父子窗口间的调用
  6. iOS开发-No matching provisioning profiles found解决方法
  7. photoshopcs5 win7安装报错的解决
  8. [RxJS] Filtering operators: distinct and distinctUntilChanged
  9. 使用php glob函数查找文件,遍历文件目录(转)
  10. 数学之路-python计算实战(20)-机器视觉-拉普拉斯算子卷积滤波