用户
 找回密码
 入住 CI 中国社区
搜索
查看: 6801|回复: 2
收起左侧

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

[复制链接]
发表于 2007-12-20 16:56:02 | 显示全部楼层 |阅读模式
本文的目的是抛砖引玉,希望能和大家一起交流学习如何解决实际问题。另:本文采用jquery来实现ajax

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

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

实现方法:
1、首先需要写一个处理列队的操作。
PHP的部分代码如下:
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的部分代码如下:
JS复制代码
 
$('#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下手。
JS复制代码
 
$('#button').click(function(){
 
    if(confirm("您确定要执行XX") == TRUE)
    {
           
           postRequest = setInterval(function(){    //利用setInterval来重复维持用户当前状态
 
                                   $.ajax({
                                   
                                        ...
   
                                       if(queue_info == "its your turn")
                               {
                                   clearInterval(postRequest); //如果用户开始执行请求,那么就不用再陆续发送状态了,用clearInterval来停止
 
                               }
 
                                        ...
 
                            });
                       
                        }, 2000);
 
    }
 
 
});
 
复制代码


接下来,改进PHP文件

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();
 
        ...
 
    }
 
 
}
 
...
 
复制代码



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

评分

参与人数 1威望 +5 收起 理由
Hex + 5 精品文章

查看全部评分

发表于 2007-12-20 18:28:55 | 显示全部楼层
这么好的文章!!我先顶了!加分!
 楼主| 发表于 2007-12-21 22:28:16 | 显示全部楼层
呵呵,这里面老大功劳大大地阿

本版积分规则