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秒 表示一秒钟判断一下数据状态
        }
    }
时间: 2024-10-17 12:54:10

Ajax实现的长轮询不阻塞同一时间内页面的其他Ajax请求(同域请求)的相关文章

服务器推Comet长轮询的方式与普通AJAX不断请求的方式的区别

当我们想要在浏览器实时显示某些数据,如何实现? 实现的方式有多种,最简单的既是设置一个间隔,AJAX不断发送请求,这种方式最明显的缺陷不管有没有新数据都会一直发送请求,而且这个间隔如果设置的长,及时性太差,如果间隔设置的短,每个客户端都在不断发送大量请求,影响服务器性能 还有一种是利用服务器推的技术,基于长轮询的方式,如图所示: 一开始会觉得,这个也是在不断的请求服务器端,和普通AJAX不断请求有什么区别?这是还未了解长轮询的流程.深入研究了下,发现区别很大 长轮询大致流程为: 客户端通过AJA

Gevent的长轮询实现方法详解

长轮询 1.浏览网页时,浏览器会传HTTP 请求到服务器,服务器会根据请求将网页的内容传给浏览器,但是在很多的情况下,使用者会需要看到最新的即时性资讯,例如观看股票市场行情,而在以前只能靠着重新载入网页才能获得最新信息,但是这样不但很浪费时间,也会佔用很多不必要的网络资源,并不是一个好的方式: 2.长轮询就是解决这个问题的一个办法. 什么是长轮询 1.长时间轮询(long-polling)是让服务器在接收到浏览器发出的HTTP 请求后,服务器会等待一段时间,若在这段时间里面伺服器有新的数据更新,

web通讯长连接与长轮询

基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性. 一.什么是长连接.长轮询? 用通俗易懂的话来说,就是客户端不停的向服务器发送请求以获取最新的数据信息.这里的“不停”其实是有停止的,只是我们人眼无法分辨是否停止,它只是一种快速的停下然后又立即开始连接而已. 二.长连接.长轮询的应用场景 长连接.长轮询一般应用与WebIM.ChatRoom和一些需要及时交互的网站应用中.其真实案例有:WebQQ

php+ajax长轮询实现web即时聊天

web im的实现方式有很多种: 1.普通轮询,原理通过js定时重复发送ajax请求服务端,获取数据后显示. 2.长轮询,ajax请求服务端,服务端有数据会立即返回,服务端无数据时,会一直等待,直到有数据了才立即范围. 3.socket长连接. 特征分析: 方法1:实现起来最容易,定时重复请求服务端会产生无意义的http连接,消耗服务端资源,实时性较差. 方法2:实现起来较容易,会减少无效的ajax请求产生的http连接,能即时返回数据,但服务端会一直挂着,会消耗一定的资源,处理并发能力不强,比

用大白话揭开Ajax长轮询(long polling)的神秘面纱

在看这篇Ajax长轮询之前可以先看看Ajax轮询技术(没有长),有助于理解: Ajax长轮询属于Ajax轮询的升级版,在客户端和服务端都进行了一些改造,使得消耗更低,速度更快. "不间断的通过Ajax查询服务端". 来,小二,先上代码~: Reception.html //客户端 <html> <head> <title></title> <script src="http://lib.sinaapp.com/js/jqu

PHP实现Ajax长轮询

传统的AJAX轮询方式,客服端以用户定义的时间间隔去服务器上查询最新的数据.种这种拉取数据的方式需要很短的时间间隔才能保证数据的精确度,但太短的时间间隔客服端会对服务器在短时间内发送出多个请求. 反转AJAX,就是所谓的长轮询或者COMET.服务器与客服端需要保持一条长时间的请求,它使得服务器在有数据时可以返回消息给客户端. 这里使用AJAX请求data.php页面获得'success'的值,请求的时间达到80秒.在这80秒中若没有从服务端返回'success'则一直保持连接状态,直到有数据返回

ajax长轮询 (转)

javaWeb项目中需要一个实时提醒的功能,也就是某人做了某一操作,可以立即提醒到当前在线的用户 最开始想在用户做了操作后,储存一个状态到数据库中然后用每隔几秒用ajax去请求后台查询数据库来确定是否显示提醒窗口 提醒窗口使用jquery easyui 的messager 在右下角弹出如下图 后查得可通过AJAX长轮询的方法来解决频繁对后台的请求,进一步减小压力 在实现过程发现AJAX的多次请求会出现多线程并发的问题又使用线程同步来解决该问题 个人对ajax长轮询的一点愚见 ajax请示后台时,

ajax长轮询实现即时聊天室

前段js: //处理ajax长轮询 $(function(){ ask_order(); function ask_order(){ var ask_action = "{:U('index/order_commet',array('time'=>10,'desk_id'=>$desk_id))}"; $.ajax({                    type:"GET",                    dataType:"jso

ajax轮询session阻塞问题

近来读了几篇关于ASP.NET下Session机制的文章,结合自己的实际应用,有点感想: 在ASP.NET的Session的默认机制下,对同一个SessionID下的用户请求ASP.NET的Session数据的操作会引起排他锁,假设在同一个SessionID下有多个用户同时请求Session数据的话,就会出现很大的延迟现象.把Session的信息设置为ReadOnly,将不会在导致排他锁的出现.但是,只读Session'数据的操作还是要等待对Session的读写操作引起的排他锁的释放. 因此在不