ThinkPHP长连接+Ajax轮询

浏览:8176 发布日期:2014/09/12 分类:求助交流 关键字: 长连接 轮询 Ajax ThinkPHP 时间线过长
我使用长连接+轮询方式做客服聊天系统:

1、基于ThinkPHP框架编码

2、CostomerAction中有两个方法:send_message() 和 get_message()。

3、客户端使用ajax轮询方式调用get_message()获取数据,使用点击发送事件通过ajax调用send_message()插入数据。

4、进入聊天窗口后,ajax轮询即启动。

出现问题:当在文本域输入文字,点击“发送”后,消息并未被及时处理,得等待get_message()超时返回之后,send_message()才能成功执行。起初我以为是get_message()方法中不断查询数据库(而ThinkPHP数据库锁住导致send_message()方法中无法插入数据而形成的等待)。但当我把两个方法中的数据库操作都注释之后,依然存在问题。

注:我使用传统的方式的方式编码,长连接+轮询文件:get_message.php。和发送数据文件:send_message.php。这种方式,没有出现以上问题。

请问:这个问题怎么解决?

部分代码如下:/**
 * 长连接+轮询调用获取信息的方法
 */
public function get_message() {

    $loginer = session("loginer");
    // 接受者id
    $to = $loginer['id'];
    // 发送者id
    $from = I('from');
    // 超时时间
    $out_time = 80;
    //
    // 创建内容模型
    $Content = M('Content');
    // 根据from to 两个字段获得对应的聊天消息
    $map['to'] = (int)$to;
    $map['from'] = (int)$from;
    $map['isread'] = array('neq', 1);

    set_time_limit(0);
    $i = 0;
    while(true) {
        usleep(500000);
        $i++;
        
        // 获得数据
        $res = $Content->where($map)->select();
        // 
        if($res){
            $content = "";
            $ids = array();
            foreach ($res as $value) {
                $content .= $value["content"] . "<br />";
                $ids[] = $value["id"];
            }
            unset($map);
            $map["id"] = array("in", $ids);
            $data["isread"] = 1;
            $Content->where($map)->save($data);
            $msg['success'] = "1";
            $msg['content'] = $content;
            $msg['to'] = $res[0]["to"];
            $msg['from'] = $res[0]["from"];
            $this->ajaxReturn($msg, "JSON");        
            break;     
        } 

        // 服务器($_POST['time'] * 0.5)秒后告诉客服端无数据      
        if($i >= $out_time){      
            // $arr = array('success'=>"0",'name'=>'xiaocai','text'=>$rand); 
            $msg['success'] = "0";
            $msg['content'] = "";
            $this->ajaxReturn($msg, "JSON"); 
            break;     
        }
    }
}
/**
 * 发送信息方法
 */
public function send_message() {
    // 获取当前用户的信息:已登录或临时用户
    $loginer = session("loginer");
    $from = $loginer["id"];
    if ($from != I('from')) {
        $info['state'] = "-1";
        $this->ajaxReturn($info, "JSON");
        exit;
    }
    // 获取要发送到的用户ID
    $to = I('to');
    // 获得客户端提交的数据,并插入数据库中
    $content = I('content');

    // 定义数据模型
    $Content = M('Content');
    $data["from"] = (int)$from;
    $data["to"] = (int)$to;
    $data["content"] = $content;
    $res = $Content->add($data);

    // 插入成功这返回成功提示信息,便于客户端显示处理
    if ($res) {
        $info["state"] = "1";
    } else {
        $info["state"] = "0";
    }
    // 
    $info["content"] = I('post.content');
    $this->ajaxReturn($info, "JSON");
}
前端Js代码:<script type="text/javascript">
    var sender = "{$from_name}";
    var toer = "{$to_name}";
    var from = "{$from}";
    var to = "{$to}";

    // Ajax轮询
    $(function() {
        var get_message = {
            type: "POST",
            url: "{:U('Customer/get_message')}", 
            timeout: 80000, //ajax请求超时时间80秒      
            data: {
                now: new Date().getTime(),
                from: to,
                to: from
            },//40秒后无论结果服务器都返回数据      
            success: function(data, textStatus) {
                //从服务器得到数据,显示数据并继续查询      
                if (data.success == "1") {
                    console.info(data.success + " " + data.to + " " + data.content);
                    var get = toer + "对" + sender + "说:<br/>";
                    get += " " + data.content + "<br/>";
                    $("#record").append(get);
                    $.ajax(get_message);
                }
                //未从服务器得到数据,继续查询      
                if (data.success == "0") {
                    $.ajax(get_message);
                }
            },
            // Ajax请求超时,继续查询      
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                if (textStatus == "timeout") {
                    console.info("请求超时!");
                    $.ajax(get_message);
                }
            }
        };
        $.ajax(get_message);
    });

    // Ajax提交数据
    $(function() {
        $("#btn_send").click(function() {
            $.ajax({
                url: "{:U('Customer/send_message')}",
                type: "POST",
                data: {
                    to: to,
                    from: from,
                    content: $('#content').val(),
                    now: new Date().getTime()
                },
                success: function(data) {
                    if (data.state == "1") {
                        var send = sender + "对" + toer + "说:<br />";
                        send += $('#content').val() + "<br/>";
                        $("#record").append(send);
                        $('#content').val("");
                    } else {
                        alert("发送失败" + data);
                    }
                }
            })
        });
    });
</script>
最佳答案
评论( 相关
后面还有条评论,点击查看>>