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

[Ajax] 请教一个关于iframe实现反向Ajax的问题

[复制链接]
发表于 2017-7-1 15:49:09 | 显示全部楼层 |阅读模式
这个问题源于一个贴子<<使用反向Ajax技术做在线客服系统>>,地址如下
使用反向Ajax技术做在线客服系统
http://blog.csdn.net/baochao95/article/details/52822098
原PHP的方式已经实现,确实可用。之后就想着用CI改写一下。碰到如下问题。
控制器中kefu_iframe部分,无论如何调整都无法实现iframe长连接功能,只能加了exit('55555')后,会实现客服和系统对话功能,但只能执行一次。查了挺多资料,都没有办法实现来回对话的交互功能。
分析了几点:
①CI的VIEW缓存问题,感觉是控制器中的内容如果不执行完,VIEW部分是无法加载的。
②sleep在中间似乎不起作用。



控制器文件 Ajaxke.php
PHP复制代码
 
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class Ajaxke extends Controller {
 
    /**
     * Index Page for this controller.
     *
     * Maps to the following URL
     *      http://example.com/index.php/welcome
     *  - or -
     *      http://example.com/index.php/welcome/index
     *  - or -
     * Since this controller is set as the default controller in
     * config/routes.php, it's displayed at http://example.com/
     *
     * So any other public methods not prefixed with an underscore will
     * map to /index.php/welcome/<method_name>
     * @see https://codeigniter.com/user_guide/general/urls.html
     */

 
    public function __construct(){
        parent::__construct();
        // $this->db->close();
        $this->load->model('m_ajax');  
 
    }
    public function index()
    {
 
        $this->load->view('ajaxkefu_admin', TRUE);
 
    }
 
    public function kefu_iframe(){
        //<meta http-equiv="Content-Type" content="text/html"; charset=utf-8">
        //$this->output->set_content_type('text/plain', 'UTF-8');
        // $this->output->set_content_type('text/html', 'UTF-8');
        // echo $this->output->get_header('content-type');
        echo '************';
        // echo $this->output->get_header('content-type');
        // exit();
        header('Content-type:text/html; charset=utf-8');
        set_time_limit(0);
        // ob_start();
        ob_end_clean();
        echo str_pad(' ', 4096);  
        // ob_flush();
        // flush();
 
 
        while (true) {
            $sql = "select * from msg where rec = 'admin' and isread = 0 limit 0,1";
            $msg = $this->m_ajax->getOnemsg($sql)->row_array();
            // echo $msg; echo '<br />';
            if (!empty($msg)) {
                ob_end_clean();
                $sql = 'update msg set isread = 1 where mid = '.$msg['mid'];
                // echo $sql; exit('333333333');
                // parent.window.comet({"mid":"28","rec":"admin","pos":"asdf","isread":"0","content":"asdfasdf"})
                $this->m_ajax->getOnemsg($sql);
                $json = json_encode($msg);
                // sleep(5);
                echo "<script>parent.window.comet($json); </script>";  
                // sleep(5);
                $this->output->_display();
                exit('55555555555555');
                ob_flush();
                flush();
                sleep(1);
            }
 
            sleep(1);          
        }
 
    }
 
 
    public function kefu_ajax(){
        set_time_limit(0);
        $rec = $_COOKIE['username'];
        $sql = "select * from msg where rec = '$rec' and isread =0 limit 0,1";
        // exit($rec);
        while (true) {
            $msg = $this->m_ajax->getOnemsg($sql)->row_array();
 
            if (!empty($msg)) {
                $sql = "update msg set isread = 1 where mid = ".$msg['mid'];
                $this->m_ajax->getOnemsg($sql);
                echo json_encode($msg);
                exit();
            }
            sleep(1);
        }
    }
 
    public function kefu_sendmsg(){
        header('Content-type:text/html;charset=utf-8');
        // $db = $this->load->database('ajax',true);
        $rec = $_POST['rec'];
        $pos = $_COOKIE['username'];
        $respContent = $_POST['content'];
 
        // $rec = 'admin';
        // $pos = 'still';
        // $respContent = 'come on ';
        $sql = "insert into msg (pos,rec,content) values ('$pos', '$rec', '$respContent')";
        $res = $this->m_ajax->insertOnemsg($sql);
        echo $res?'ok':'fail';    
    }
 
 
    public function keuser()
    {
 
        setcookie('username', 'user'.rand(10000,99999));
        $this->load->view('kefu_user');
 
    }
 
}
 
 
 
复制代码



视图文件:ajaxkefu_admin.php
HTML复制代码
 
<?php
   setcookie('username','admin')
?>
<html>
<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Closest — 100% Free Fully Responsive HTML5 Template by FREEHTML5.co</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Free HTML5 Template by FREEHTML5" />
    <meta name="keywords" content="free html5, free template, free bootstrap, html5, css3, mobile first, responsive" />
 
    <!--ajaxke.css -->
    <link rel="stylesheet" href="<?php echo _CSSPATH_ ; ?>style.css">
    <script src="<?php echo _JSPATH_ ; ?>kefuadmin.js"></script>
 
 
    <!-- Facebook and Twitter integration -->
    <meta property="og:title" content=""/>
    <meta property="og:image" content=""/>
    <meta property="og:url" content=""/>
    <meta property="og:site_name" content=""/>
    <meta property="og:description" content=""/>
    <meta name="twitter:title" content="" />
    <meta name="twitter:image" content="" />
    <meta name="twitter:url" content="" />
    <meta name="twitter:card" content="" />
 
    <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
    <link rel="shortcut icon" href="favicon.ico">
 
    <link  rel='stylesheet' type='text/css'>
 
 
    </head>
<body>
 
    <h1>客服功能--客服人员端</h1>
    <h2>原理:iframe+长连接</h2>
 
    <div id="chatArea">  
    </div>
        <hr>  
        <iframe name="frame" frameborder="0" src="<?php echo __ADMIN__DO_MAIN; ?>/ajaxke/kefu_iframe"></iframe>
        <p>咨询人:<span id="postman"></span></p>
        <p><textarea id="respContent"></textarea></p>
        <p><input type="button" value="回复" /></p>
 
</body>
</html>
 
 
 
复制代码

发表于 2017-7-2 16:49:46 | 显示全部楼层
你说对了,确实是控制器不执行完不会输出视图,因为用了 output buffer,你可以强制 flush,或者修改下 CI 源码
 楼主| 发表于 2017-7-2 18:03:29 | 显示全部楼层
Hex 发表于 2017-7-2 16:49
你说对了,确实是控制器不执行完不会输出视图,因为用了 output buffer,你可以强制 flush,或者修改下 CI  ...

感谢,您说的强制flush,是指在循环中使用ob_flush()和flush()么?这个已经用了,但似乎并不起什么作用。现在在修改CI源码解决这个问题。
解决这个问题的时候,闪出这样一个想法。其实像Iframe长连接的这种技术并不适合http这种无状态,或者理解为当年Ajax的一种变通。
感谢您!
发表于 2017-7-3 10:23:25 | 显示全部楼层
洛必达法则 发表于 2017-7-2 18:03
感谢,您说的强制flush,是指在循环中使用ob_flush()和flush()么?这个已经用了,但似乎并不起什么作用。 ...

你可以看看 http://codeigniter.org.cn/user_guide/libraries/output.html 里的 _display 方法。
 楼主| 发表于 2017-7-7 16:33:39 | 显示全部楼层
尝试了两种方法,一种在_display中修改,另外一种在loader下的view中修改。_display修改有些效果,但是真正交互没有完全实现,基本就是对话两次到三次。
之后,讨巧在resp()下加了自刷新,基本实现多次对话,但由于刷新了页面,相当于cookie也修改了,不太完美。
所以修改__display()路数还是比较靠谱的。
由于最近工作比较紧张,加上初识CI,暂时研究自此,算在TODO LIST下。等有空闲时间好好研究一下CI。
非常感谢@Hex 指点!!!

评分

参与人数 1威望 +3 收起 理由
Hex + 3 赞一个!

查看全部评分

本版积分规则