wesleywray 发表于 2007-12-20 16:56:02

利用ajax实现用户列队执行请求的应用

本文的目的是抛砖引玉,希望能和大家一起交流学习如何解决实际问题。另:本文采用jquery来实现ajax

首先,说明需要解决的问题:
由于一些外部命令对系统资源消耗过大,多用户同时进行操作很容易造成服务器瘫痪,所以需要将用户的请求按提交顺序一个个的单独执行。

解决思路:
当有请求触发时,利用AJAX提交请求,返回列队信息,当列队到达顶点时(即:轮到该用户执行请求了),再接受表单信息或者其他信息。

实现方法:
1、首先需要写一个处理列队的操作。
PHP的部分代码如下:

<?php
class Ctl extends Controller
{

    ...


    function queue()
    {
       ...
       //首先判断此用户是否在用户列队数据表中,如果没有在列队中,则添加
         $data = array(
                        'sessId'         => $this->session->userdata('session_id'), //这里我用sessionID来规定了某一用户或者说某一操作的唯一标识
                        'lastActivity'   => date('U'));
            $this->db->insert('tbl', $data);
            
         $this->db->where("id < {$this->db->insert_id()}");
            $query = $this->db->get('tbl');
            $count = $query->num_rows(); //得到该用户或该次操作前面还有多少请求在列队中


      ...

      //如果用户在列队中,则更新他的最后活动时间

            $data = array(
                        'lastActivity'   => date('U'));
            $this->db->where(..);
            $this->db->update('tbl', $data);

            $this->db->where("id < {...}");
            $query = $this->db->get('tbl');
            $count = $query->num_rows();
   
      ...


       $count == 0 ? echo "its your turn" : echo $count;

    }

    ...


}
?>


2、接着需要写一个ajax来提交执行请求.
Javascript的部分代码如下:

$('#button').click(function(){

    if(confirm("您确定要执行XX") == TRUE)
    {

            $.ajax({
                  url:"http://your/domain/ctl/queue",
                  type:"GET",
                  cache:false,
                  dataType:"text",       //当然用XML,JSON,HTML都可以,为了简单实现功能,我用text举例
                  success:function(queue_info){ //queue_info是用来接收ctl/queue返回的信息

                            if(queue_info == "its your turn")
                            {
                                 //.... 如果返回信息为列队顶部,则执行....

                            }
                           else
                            {
                                 alert("您前面还有" + queue_info + "位用户在排队,轻稍候...");

                            }



                  }

            });


    }


});



经过以上的两步会发现,执行请求通过AJAX只执行了一次,如果用户在等待列队的过程中关闭了页面,则他的列队信息将保留在数据表中,导致后面的用户永远无法执行操作。于是我们需要改进JS,让他实现每隔一段时间发送一次当前状态。而PHP需要加入判断并删除用户已经离开的信息。

改进工作先从JS下手。

$('#button').click(function(){

    if(confirm("您确定要执行XX") == TRUE)
    {
            
         postRequest = setInterval(function(){    //利用setInterval来重复维持用户当前状态

                                 $.ajax({
                                    
                                        ...
   
                                       if(queue_info == "its your turn")
                               {
                                 clearInterval(postRequest); //如果用户开始执行请求,那么就不用再陆续发送状态了,用clearInterval来停止

                               }

                                        ...

                            });
                        
                        }, 2000);

    }


});


接下来,改进PHP文件


...

function queue()
{
    //由于JS是随便一个人都能看到的。为了防止有人恶意刷新列队处理页面,我们可以用一些措施来防范。比如referrer来判断用户是否是从某一页面访问的列队处理页面。
    $this->load->library('user_agent');
    if($this->agent->referrer() == '...'){

      $current = date('U');
      $expire= $current - 5; //假定我们认为5秒未受到某一个用户的活动信息,就杀掉该ROW

       $this->db->where("lastActivity < {$expire}");
      $this->db->delete();

      ...

    }


}

...



以上就大致架构出用户列队执行的效果。当然本文的还是以方法和方式为重点。与其给出全部代码,不如把整个设计过程阐述清晰,(授人以鱼,不如授人以渔)。大家要是有什么更好的方法或者改进,还请多多发言

Hex 发表于 2007-12-20 18:28:55

这么好的文章!!我先顶了!加分!

wesleywray 发表于 2007-12-21 22:28:16

呵呵,这里面老大功劳大大地阿
页: [1]
查看完整版本: 利用ajax实现用户列队执行请求的应用