2013-05-25 40 views
0

後臺定期需要向連接到Web應用程序的客戶端發送數據。 這裏是劇本我已經安裝:來自PHP輪詢mySQL的服務器發送的事件

<?php 
header("Content-Type: text/event-stream\n\n"); 
header('Cache-Control: no-cache'); 

flush(); 
ob_flush(); 

require_once('connect.php'); 
//connect to the database 
$mysql = mysql_connect($hostname, $username, $password) or die ('cannot reach database'); 
$db = mysql_select_db($database) or die ("this is not a valid database"); 
mysql_query("SET NAMES 'utf8'", $mysql); 

$query = mysql_query("SELECT * FROM `clientEvents` ORDER BY id DESC LIMIT 1") or die(mysql_error()); 
    $row = mysql_fetch_array($query); 
    $index = $row["id"]; 
    echo $index; 

loop($index); 

function loop($index){ 
while (1) 
{ 
    ob_implicit_flush(true); 
    $buffer = str_repeat(" ", 4096); 
    echo $buffer."\n"; 

// Every second, look for new question. 

$query = mysql_query("SELECT * FROM `clientEvents` WHERE id>$index ORDER BY id DESC LIMIT 1") or die(mysql_error()); 
$row = mysql_fetch_array($query); 
if(mysql_num_rows($query)>0) 
{ 
    if($row["type"]=="pushCustomQuestion"){ 
    pushCustomQuestion($row["data"],$row["id"]); 
    break; 
    } 
    else if($row["type"]=="pushGameTimeEvent"){ 
    pushGameTimeEvent($row["data"],$row["id"]); 
    break; 
    } 
} 
sleep(3); 
} 

function pushGameTimeEvent($id,$index) { 
    //echo "id for game event:".$id; 
    $result = mysql_fetch_array(mysql_query("SELECT * FROM game_events WHERE id = $id LIMIT 1")); 

    //$num_results = mysql_num_rows($result); 

    echo "event: new_game_event\n"; 
    echo 'data: { "id": "' . $result['id'] . '",' 
        .'"match_id": "' . $result['match_id'] . '",' 
        .'"minute": "' . $result['minute'] . '",' 
        .'"event_id": "' . $result['event_id'] . '",' 
        .'"event_name": "' . $result['event_description'] . '",' 
        .'"player_name": "' . $result['player1_name']. '",' 
        .'"player2_name": "' . $result['player2_name'] . '",' 
        .'"which_half": "' . $result['which_half'] . '",' 
        .'"team_logo": "' . $result['team_logo'] . '"}'; 
    echo "\n\n"; 
    ob_flush(); 
    flush(); 
    sleep(10); 
    loop($index); 
} 

一切似乎工作確定,直到七個客戶機加載Web應用程序,一切豬。這個腳本有問題嗎?

在我看來,我這樣做的方式是違反直覺的,因爲我正在輪詢數據庫以發送新事件。有沒有其他更好的方法來從後臺應用程序觸發事件?

感謝您的任何幫助。

+0

我看起來好像你的apache只允許7個開放的未應答並行連接,並且你的輪詢不是客戶端,但php和html連接保持打開很長時間。 – flaschenpost

+1

@yvytty,頻率是用sleep()方法控制的。每3秒鐘一次,循環將繼續檢查數據庫是否有新條目。 –

+0

@flaschenpost的確,連接保持打開,這是服務器發送事件的工作方式(除非我誤解了某些內容) –

回答

0

這可能與Apache一次對可連接的人數限制有關。

這是一個巨大的長輪詢的教程,是從你已經安裝有一點不同: http://elikirk.com/2012/04/17/php-ajax-long-polling-comet-demonstration/

但是,如果你想擴展此,長輪詢不是實時「推」最好的解決辦法。

我建議看看node.js和sockets.io,因爲這些技術都是專門爲此而設計的。缺點是node.js實際上是它自己的運行javascript的服務器,所以你將不得不放棄php。但是有一些解決方法可以通過CURL橋接node.js和php。

+0

您必須是正確的。 Apache和連接數可能是罪魁禍首。還要感謝張貼長輪詢教程,但恐怕檢查文件不會。 –

+0

此外,nodejs似乎肯定是一個更好的解決方案,但應用程序必須駐留在apache vps中。我現在檢查出使用ZeroMQ http://www.zeromq.org/的可能性,如果我成功安裝它:) –