2012-09-11 116 views
0

我在我的網站上使用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; 
} 

回答

1

下面是我們在現場sysyem使用的想法。當事件發生時,爲其添加時間戳。例如。

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); 
} 
+0

這正是我需要的!萬分感謝。 – alhimikst