ajax 长轮循

来源:互联网 发布:华为手机修改mac地址 编辑:程序博客网 时间:2024/05/18 06:47

长轮循:

使用ajax技术,使服务器端和客户端之间建立连接,客户端发送请求,服务器端隔一定时间检查数据库是否有变动,没有变动,返回给客户端的数据为空,即可以是data='',还可能有个提示信息的返回变量msg='超时'。当检查到数据变动了,则服务器端返回数据,data='数据',msg='成功',客户端则做相应处理,处理完立即再次调用函数,与服务器端保持连接;服务器端会设定一定的时间,当超过这个时间数据库没有变化,就向客户端返回超时的信息,让客户端做处理,然后在建立连接关系。无论成功还是失败,都要在此次进行长轮询。


下面这个例子是轮询红包的状态变化:status=0,显示倒计时;status=1,处于抢红包状态;status=2,如果还有下一轮红包活动,则提示还有下一轮红包活动;如果没有下一轮抢红包活动,则显示活动已经结束。一进来该页面,就要显示相应状态的界面信息,然后处理当前有效的红包,才进入长轮询函数。

思路如下:

1、设置变量:

      current_redbag用于存储当前有效的红包活动信息,redbags存储所有红包活动信息。

2、函数requestRedbags(activity_id)的作用是根据活动的id号,前端向后台请求该活动的红包信息,并将请求到的红        包信息全部保存在全局变量redbags里面。

3、函数getAvailableRedbag()获取当前有效的红包,若没有有效的红包,则返回null

4、函数handleRedbag(redbag),处理当前有效的红包,即根据当前有效红包的status来进行相应的处理

5、函数check_redbag_status(redBagId,oldStatus,timeOut,startTime) 是检查红包状态变化的长轮询,参数redBagId        是当前该轮红包的id,oldStatus是上次红包的状态,timeOut超时的时间,startTime是开始摇红包开始的时间,          用 于倒计时的。无论成功还是失败,都要在此次进行长轮询

$(function() {    var SHAKE_THRESHOLD = 1800;    var last_update = 0;    var x = y = z = last_x = last_y = last_z = 0;    var num = 0;                        var shake_status = 0;                                    //0:未开始,1:正在进行 2:已结束                                   var activity_id = "96";                                                                                                                                                                                  var current_redbag;                                                                          var redbags;                                                                                  var time_distance = 0;//本地时间和服务器时间的差                                                                                                                                                                                                                                                                var numMax = 30;                                                                                  // 请求红包列表,并对数据进行处理    requestRedbags(activity_id);        // --检测设备是否有摇一摇动作    function deviceMotionHandler(eventData) {        var acceleration = eventData.accelerationIncludingGravity;        var curTime = new Date().getTime();        shake_status = 1;        if ((curTime - last_update) > 100) {            var diffTime = curTime - last_update;            last_update = curTime;            x = acceleration.x;            y = acceleration.y;            z = acceleration.z;            var speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;            if (speed > SHAKE_THRESHOLD) {                // times++;                handelShakingMotion();            }            last_x = x;            last_y = y;            last_z = z;        }    }    // 设备有摇一摇动作,则对页面已摇次数进行加1,若已经摇到最大次数numMax,则请求抢红包接口    function handelShakingMotion() {        if (shake_status == 2 || shake_status == 0) {            return false;        }        num++;        // 添加摇一摇的声音        $('#shakingAudio').trigger('play');        document.getElementById("numberCount").innerHTML = num;        // setTimeout(function() {        // times = 0;        if (num == numMax) {            num = 0;            shake_status = 2;            // 关闭摇一摇的接口            window.removeEventListener("devicemotion", deviceMotionHandler);            // 添加摇到红包的声音            $('#shakingResult').trigger('play');             // 摇一摇结束之后,请求抢红包接口            drawRedbag(openid);        }        // }, 100); //测试得知80是比较理想的数值    }        // 发送抢红包请求    function drawRedbag(openid){        console.log("drawRedbag");        var url = globalConfig.pre_api_url + "/wxwall_api/redbag/draw_redbag.php";        var param = {            "openid":openid        };        request(url,param,function(response){            // 请求抢红包接口成功            var redBagData = response.data;            // $('#shakingResult').trigger('play');            price = redBagData.price;            refreshView(current_redbag,true);            console.log(response.msg);        });    }    // 抢红包进行中,监听摇一摇的动作    function listenPhoneShake() {        if (window.DeviceMotionEvent) {            window.addEventListener('devicemotion', deviceMotionHandler,false);            console.log("addEventListener devicemotion");        } else {            alert('抱歉,你的手机配置实在有些过不去,考虑换个新的再来试试吧');        }    }    // 当前红包:刷新界面    function refreshView(redbag,is_show_redbag){        // 显示没有红包        if( redbag === undefined ){            $('#shake_view').hide();            $('#countdown').hide();            $('#redBagInfo').hide();            $('#nextRedBagActivity').hide();            $('#activityEnd').hide();            $('#redbagRecordPage').hide();            $('#noRushRedbag').hide();            $('#noData').show();            return;        }        // 有红包,但都已经无效了        if (redbag === null) {            $('#shake_view').hide();            $('#countdown').hide();            $('#redBagInfo').hide();            $('#nextRedBagActivity').hide();            $('#activityEnd').hide();             $('#noData').hide();            // 显示红包记录/或者没有抢到红包            getRedbagRecord();            // $('#redbagRecordPage').show();            return;        }        var status = redbag.status;        if (status == '0') {            //显示倒计时            $("#shake_view").hide();            $('#redBagInfo').hide();            $('#nextRedBagActivity').hide();            $('#activityEnd').hide();            $("#countdown").show();            }else if (status == '1'){            if (is_show_redbag == true) {                $('#hostName').text( activity_title + "的红包" );                $('#fee').text('成功抢到' + price +'元');                $('#shake_view').hide();                $('#nextRedBagActivity').hide();                $('#activityEnd').hide();                $("#countdown").hide();                  $('#redBagInfo').show();                return;            }else{                //显示摇一摇                $("#countdown").hide();                 $('#redBagInfo').hide();                $('#nextRedBagActivity').hide();                $('#activityEnd').hide();                  $('#redBagInfo').hide();                $("#shake_view").show();            }                   }else if(status == '2'){            // 判断是否还有下一轮红包,在用户没有抢到红包的情况下,             // 有下一轮红包就显示进入下一轮,没有的话就显示活动结束            // 当用户抢到红包,就不会进入这种情况            var nextRedbag = getAvailableRedbag();            if (nextRedbag == null) {                //若无,显示已经结束;.......                $('#redBagInfo').hide();                $("#shake_view").hide();                 $("#countdown").hide();                 $('#nextRedBagActivity').hide();                  if( price == 0 ){                    $('#endActivityPageTxt').text('很可惜,您没抢到红包');                }else{                    $('#endActivityPageTxt').text('成功抢到' + price + '元');                }                $('#activityEnd').show();            }else{                //若有,显示还有下一轮......                $('#redBagInfo').hide();                $("#countdown").hide();                 $('#activityEnd').hide();                $("#shake_view").hide();                if( price == 0 ){                    $('#promst').text('很可惜,您没抢到红包');                }else{                    $('#promst').text('成功抢到' + price + '元');                }                $('#nextRedBagActivity').show();            }        }    }    // 获取当前有效的红包    function getAvailableRedbag(){        var length = redbags.length;        // 没有红包活动返回null        if (length == 0) {            return null;        }        // 遍历红包列表,取到第一个有效的红包,若有则返回当前有效的红包        for(var i = 0; i < length; i++){            var redbag = redbags[i];            var status = redbag.status;            // 主要获取到第一个有效的红包就返回当前有效的红包,并且退出该函数            if (status != '2') {                return redbag;                break;            }        }        // 没有有效的红包,即所有的红包活动都结束了        return null;           }    // 开始摇红包倒计时    function startCount(startTime) {          // var timeContent = $('#timeContent');   //显示倒计时的框        var endTime = new Date(startTime.replace(/-/g,'/'));     //红包开始的时间        var countTimer = setInterval(            function() {                var nowTime = new Date();                var time = endTime.getTime() - nowTime.getTime() + time_distance; //截止时间和开始时间相差的毫秒数                if (!isNaN(time) && time >= 0) {                    var day = parseInt(time / 1000 / 60 / 60 / 24);                    var hour = parseInt(time / 1000 / 60 / 60 % 24);                    var minute = parseInt(time / 1000 / 60 % 60);                    var second = parseInt(time / 1000 % 60);                    if (time == 0) {                        current_redbag.status = "1";                        refreshView(current_redbag,false);                    }else if (time <= 10000) {                        // 调用10秒倒计时动画                        $('#timeContent').text( second + '秒' );                    } else if (time <= 120000) {                        // 倒数120秒的时候                        var secondLeft = minute * 60 + second;                        $('#timeContent').text( secondLeft + '秒');                    } else {                        $('#timeContent').text( day + '天' + hour + '小时' + minute + '分钟' + second + '秒');                    }                } else if (time < 0) {                    clearInterval(countTimer);                }            }, 1000        );    }    // 检查红包状态变化的长轮询    function check_redbag_status(redBagId,oldStatus,timeOut,startTime) {        var url = globalConfig.pre_api_url + "/wxwall_api/redbag/check_redbag_status.php"; //检查红包状态的url        var redbag_id = redBagId;        var old_status = oldStatus;        var time_out = timeOut;        var start_time = startTime;        var param = {            "redbag_id": redbag_id,            "old_status": old_status,            "time_out": time_out        };        $.ajax({            // 提交数据的类型            type: "POST",            // 提交的网址            url: url,            // 提交的数据            data: param,            // 返回数据的格式            datatype: "json",            // 在请求之前调用的函数            beforeSend: function() {            },            // 成功返回之后调用的函数            success: function(response) {                response = eval("(" + response + ")");                var status = response.status;                if (status == '2') {                    current_redbag.status = response.data.new_status;//很重要                    handleRedbag(current_redbag);                     if (current_redbag.status == '2') {                        return;                    }               }                check_redbag_status(redbag_id,current_redbag.status,time_out,start_time);                // console.log(response.msg);            },            // 执行后调用的函数            complete: function(XMLHttpRequest, textStatus) {                // console.log(textStatus);            },            // 调用出错执行的函数            error: function() {                console.log("error");                setTimeout(function(){                    check_redbag_status(redbag_id,old_status,time_out,start_time);                }, 500); //这里是500ms吗??失败后果500ms再次请求            },        });    }    // 请求红包列表    function requestRedbags(activity_id){        var get_redbag_list_url = globalConfig.pre_api_url + "/wxwall_api/redbag/get_redbag_list.php"; //获取红包列表的url        data = {            "activity_id": activity_id,        };        // 向后台请求红包列表,并根据每个红包的status进行相应的处理        request(get_redbag_list_url, data, function(response) {            var datas = response.data;            redbags = datas.redbags;            // 当没有红包活动的时候,提示没有红包            if( datas == '' || response.status == '6'){                refreshView(undefined,false);                return;            }            // redbag 存储当前有效的红包或者null            var redbag = getAvailableRedbag();            // 当有红包活动的时候,但是没有有效红包,显示抢到红包的信息            if( redbag === null ){                refreshView(null,false);                return;            }            var servie_time = new Date(datas.current_time.replace(/-/g,'/'));  //卸载下面,防止datas=‘’的时候,replace()函数出错            var local_time = new Date();            time_distance = local_time.getTime() - servie_time.getTime();     //服务器和用户的时间相差的毫秒数            // 获取红包列表            var length = redbags.length;            var redbag_id = redbag.id;            var old_status = redbag.status;            var start_time = redbag.start_time;            var time_out = 40;             current_redbag = redbag;            // 处理当前的红包            handleRedbag(redbag);            // 长轮询检测status            check_redbag_status(redbag_id,old_status,time_out,start_time);                  });          }    // 处理当前有效的红包    function handleRedbag(redbag){        var status = redbag.status;        var start_time = redbag.start_time;        //         refreshView(redbag,false);        // $("#device_log").append("<li>status:"+status+"<li>");        if (status == '0') {            //显示倒计时            startCount(start_time);        }else if(status == '1'){            //监听摇一摇            if (isTestEnv == true) {                monitor_shake();            }else{                listenPhoneShake();            }        }else if(status == '2'){            // refreshView()函数已经处理了            //结束该轮抢红包,进入了结束界面            //关闭用户可以摇红包的能力            //提示用户是否还有下一轮红包活动,如果有,则引导用户操作;如果没有,提示没有。        }    }   });