jQuery与PHP实现Ajax长轮询 ( LongPoll,微信支付结果查询, ecshop )

 

  HTTP是无状态、单向的协议,用户只能够通过客服端向服务器发送请求并由服务器处理发回一个响应。若要实现聊天室、WEBQQ、在线客服、邮箱等这些即时通讯的应用,Node.js + Web Socket 打造即时聊天程序嗨聊


  传统的AJAX轮询方式,客服端以用户定义的时间间隔去服务器上查询最新的数据。种这种拉取数据的方式需要很短的时间间隔才能保证数据的精确度,但太短的时间间隔客服端会对服务器在短时间内发送出多个请求。

 

 

1、js代码

   org_wx_get();
    function org_wx_get(){
        $.ajax({      
            type:"POST",      
            dataType:"json",      
            url:"user.php?act=longpollwxpay",      
            timeout:80000,     //ajax请求超时时间80秒      
            data:{time:"40", order:'{$order.order_sn}'}, //20秒后无论结果服务器都返回数据      
            success:function(data,textStatus){  
                if(data.success=="0"){   
                    jAlert('info',data.message,'提示');
                }else if(data.success == "1"){
                    jAlert('info',data.message,'提示');
                    setTimeout(function(){window.location.href='user.php?act=order_list';},1200);
                }else if(data.success == "2"){
                  //  jAlert('info',data.message,'提示');
                    org_wx_get() ; 
                }     
            },      
            //Ajax请求超时,继续查询      
             error:function(XMLHttpRequest,textStatus,errorThrown){      
                if(textStatus=="timeout"){org_wx_get() ; }
            }      
                  
        });  
    }

  

 

 

2、php代码

if($action == 'longpollwxpay'){
    $gmtime=gmtime();
    $order_sn = $_POST['order'] ;
    $l_time = intval( $_POST['time'] );
    if(empty($l_time)){
        die(json_encode(array('success'=>'0','message'=>'时间参数不正确!')));
    }
    if(empty($order_sn)){
        die(json_encode(array('success'=>'0','message'=>'订单不能为空!')));
    }
    if(isset($_SESSION['wxpay']['time']) && $gmtime-$_SESSION['wxpay']['time'] > 15)$_SESSION['wxpay']['number']=0;
    if( isset( $_SESSION['wxpay'] ) && $_SESSION['wxpay']['order_sn'] == $order_sn &&  $_SESSION['wxpay']['number'] > 10 ){
        $_SESSION['wxpay']['time']=$gmtime;
        die(json_encode(array('success'=>'0','message'=>'请刷新页面后,再支付!')));
    }
    $order_info = $db->getRow('SELECT order_id,pay_name FROM '.$ecs->table('order_info').' WHERE order_sn='.$order_sn);
    if( empty( $order_info ) || $order_info['pay_name'] != '微信' ){
        die(json_encode(array('success'=>'0','message'=>'订单不存在,或不是微信支付!')));
    }
    if( isset( $_SESSION['wxpay'] ) ){
        $_SESSION['wxpay']['number']++;
        $_SESSION['wxpay']['order_sn'] = $order_sn;
    }else{
        $_SESSION['wxpay'] = array('number'=>1,'order_sn'=>$order_sn);
    }

    set_time_limit(0);//无限请求超时时间      
    $i=0;   

    while ( $i < 100 ){      
        //sleep(1);      
        usleep(500000);//0.5秒      
        $i++;      
        //若得到数据则马上返回数据给客服端,并结束本次请求      
        $sql = 'SELECT order_id,extension_code FROM '.$ecs->table('order_info').' WHERE pay_status=2 AND order_sn='.$order_sn;
        $order=$db->getRow( $sql );
        if($order){
            // 加通知提示,通过cookie.在页面弹出提示
            if($order['extension_code'] === 'honus_boline'){
                setcookie('boline_note',1, gmtime() + 86400*15);
            }
            die(json_encode(array('success'=>'1','message'=>'支付成功!')));
        }
 
        //服务器($_POST['time']*0.5)秒后告诉客服端无数据      
        if($i==$l_time){      
            die(json_encode(array('success'=>'2','message'=>'超时重连接!')));
        }      
    }   
    die();
}

  

 

posted @ 2016-09-19 21:06  flyskycode  阅读(626)  评论(0)    收藏  举报