2014-01-15 109 views
1

我有一種情況,即服務器上的某些事情發生更改時,必須更新webclient。爲此,我有,在服務器端,無論是用於在PHP中將事件從服務器推送到客戶端的Websockets

  • 一個無限循環,積極收集變化
  • 回調,一個事件偵聽,勾搭成其他系統/框架/類的事件循環

當此機制發現更改或接收到事件時,它需要通過websocket將其傳遞給webclient。

雖然這很簡單,例如,在Java中,由於eventloops(線程),您有「運行應用程序」的概念,但這並不能很好地映射到PHP。 PHP旨在提供HTTP請求,本質上是無狀態的。當一個請求進入時,一個PHP腳本被執行,做一些東西並呈現一個響應,然後解散爲空。

我該如何獲得運行的服務器端PHP進程,它可以監聽事件併爲webclient提供打開websocket連接的方法?就像事件監聽者可以訂閱的獨立啓動線程一樣?

可能的解決方案,我能想到的:

場景A:PHP線程(並行線程)

如果使用PHP線程,這是它是如何工作的?

  • Web客戶端A對新線程開始舉行的WebSocket連接,做監聽工作的請求
  • 在服務器端
  • 「正常」應答/請求線程(即催生了eventlistening的一個線程)在發回迴應後結束
  • 客戶端和服務器現在已連接。客戶端A現在都有自己的線程運行在服務器上
  • 當Web客戶端者B的請求,同專門恰好爲他/她,從而創造一個新的線程,可能做同樣的工作作爲第一個從A

場景B:CRON

要模擬eventloop,可以設置一個CRON作業,以一定的時間間隔運行PHP腳本。雖然這是收集客戶感興趣的事件的工作,但您如何獲得WebSocket端點?由於此PHP腳本獨立於Web運行,因此如何將它加入到開放(?)套接字中?有人必須保持他們......

如果PHP是由於它的「腳本設計」的websockets不匹配,什麼是一個很好的選擇?

+0

你有沒有想過如何使用Node.js? – Ryan

+1

php不是多線程語言... –

+0

@MarcB:正確,但有[pthread擴展名](http://www.php.net/manual/en/book.pthreads.php) – raoulsson

回答

0

瑞奇是一個偉大的PHP的WebSocket服務器:http://socketo.me/

這是我做的:

$loop = React\EventLoop\Factory::create(); 
$pusher = new MyApp\Pusher(); 

// run ratchet as a daemon @ 0.5 second intervals 
$loop->addPeriodicTimer(0.50, function() use($pusher){ 
    //$thread = new AsyncThread\AsyncThread($pusher->clients); // Really wished this worked, but everytime i send a websocket resource to a thread the thread throws a fatal error if i attempt to bind the data and even if I dont the resource disappears /sigh 
    $pusher->load(); // so I just call this function which basically handles each client one after the other as opposed to simultaneously via threads. 
}); 

$webSock = new React\Socket\Server($loop); 

if ($loop instanceof \React\EventLoop\LibEventLoop) { 
    echo "\n HAS LibEvent"; // apparently performance is better with the libevent php extension callback installed; I haven't really noticed a significant difference 
} 

$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect 
$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
      new Ratchet\WebSocket\WsServer($pusher) 
    ), 
    $webSock 
); 

$loop->run(); 
相關問題