【问题标题】:long polling events长轮询事件
【发布时间】:2012-09-11 14:01:59
【问题描述】:

我使用 php 在我的网站上实现长轮询。一切正常,但有一个问题。当我由一个用户打开多个页面时,我无法识别,我应该在该页面上运行什么事件。如果我在一个页面上工作后阻止事件,则该事件在另一个页面上不起作用。如果我不阻止,他们会继续在每一页上无限工作。如果我检查有效页面上的事件,刷新页面后它们仍然可以再次工作。我错过了正确的解决方案,您能帮帮我吗?

代码不是很好,但可以工作

我只是想知道如何做到这一点

function loadEventAll($uid=0){
    if (isset($_POST['event_log'])){
        $event_log = json_decode($_POST['event_log']); //here event already worked on page
    }
    else $event_log = array();
    for($i=0;$i<25;$i++){            
        $now = time();
        $time = $now;//-$this->triggered_timeout;   

        //sql to cut already worked event
        $noid = array();
        foreach($event_log as $eve){
            if(isset($eve->id)) $noid[] = 'id<>'.$eve->id;
        }
        if (count($noid)) $noid = ' AND ('.implode(' AND ', $noid).') ';
        else $noid = '';   

        //don't try to understand this :)
        $q="SELECT * FROM ig_event WHERE (user_id='$uid' OR user_id=0) AND (((triggered+2>=$time OR triggered=0) AND infinite=0) OR (infinite=1 AND triggered+10<=$time)) AND ($now<time_end or infinite=1) AND time_start<=$time $noid";            
        $link = mysql_query($q); 
        $arr = array();
        if(!$link){ 
            sleep(1);
            continue; // if no event occurring start next iteration
        }
        if (mysql_num_rows($link)){   
            while ($ddd = mysql_fetch_assoc($link)){
                $id = $ddd['id'];
                if ($ddd['direct_call']!=""){ //call js function on page
                    $arr[] = $ddd['direct_call'].':'.$id.':'.$ddd['param'];

                    if ($ddd['success']!=1){
                        if (!$ddd['infinite']) $succ = ' success=1';else $succ='';
                        $ctime = time();
                        $q = "UPDATE ig_event SET $succ,triggered='$ctime' WHERE id='$id'";
                        mysql_query($q);
                    }
                }
                else{ // usually not used
                    if ($this->load->module($ddd['module'])){
                        if (method_exists($this->$ddd['module'], $ddd['action'])){

                            $time = time();                                
                            if (($tarr = $this->$ddd['module']->$ddd['action']($ddd['param'])) and !$ddd['infinite']){                                    
                                $q = "UPDATE ig_event SET success=1 WHERE id='$id'";
                                mysql_query($q);
                            }
                        }
                        else{
                            $q = "UPDATE ig_event SET success=1 WHERE id='$id'";
                            mysql_query($q);
                        }
                        $q = "UPDATE ig_event SET triggered='$time' WHERE id='$id'";
                        mysql_query($q);
                        if (!$ddd['infinite']) $arr[] = 'blank'.':'.$id.':';
                    }    
                }
            }    
            return $arr;
        }  
        sleep(1);
    }  
    return $arr;
}

【问题讨论】:

    标签: php long-polling


    【解决方案1】:

    这是我们在实时系统中使用的一个想法。当事件发生时,为其添加时间戳。例如

    id | col1 | col2 | timestamp
    ------------------------------
     1 | herp | derp | 1347373151
     2 | herp | derp | 1347373152
     3 | herp | derp | 1347373153
    

    现在,当我们开始长轮询时,我们会发送我们捕获的最后一个事件的时间,或者如果它是第一个请求 - 当前时间。然后我们构建查询:

    $q = "SELECT * FROM `table` WHERE `timestamp` < ".$lastCaughtEventTime;
    

    如果你得到任何结果 - 返回它们并退出 php 脚本。 js 端应在从结果集中获得具有最高时间戳的答案后立即重复请求。这样,您的查询将最小且快速。示例代码:

    function poll() {
        $results = [];
        $start = microtime(true);
        $q = "SELECT * FROM `table` WHERE `timestamp` < " . (int) $_POST['timestamp'];
        while (true) {
            $result = mysql_query($q);
            if (mysql_num_rows($result) > 0) {
                $result = returnResults($result);
                break;
            }
            else {
                if (time() - $start > POLLING_TIMEOUT) {
                    die('timeout');
                }
                sleep(2);
            }
        }
        echo json_encode($result);
    }
    

    【讨论】:

    • 这正是我所需要的!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2013-08-08
    • 2011-04-20
    • 2019-05-28
    • 2012-03-07
    • 1970-01-01
    • 2012-11-30
    • 2012-02-24
    • 2015-01-23
    相关资源
    最近更新 更多