2012-04-03 60 views
0

我正在做一個有2個客戶端的小型php服務器,連接到php(設備a)並控制其他設備(設備b)。PHP - 回聲做其他客戶端

設備a向php發出請求。現在我想將該命令推送到設備b。有什麼辦法回聲到設備B?或向設備發出請求b?

(我只需要發送一個字符設備b)

回答

2

推到設備是可能的,但取決於您的設備。 一個解決辦法是的WebSockets,請參閱進一步閱讀下列鏈接:

http://www.websocket.org/

http://code.google.com/p/phpwebsocket/

另一個解決方案是longpolling這是很容易在PHP來實現: http://en.wikipedia.org/wiki/Push_technology#Long_polling

很簡單服務器端的長時間執行:

$ts = time(); 
while(true) { 
    // if there's something new, send the response to the server 
    // if not, continue with the loop 
    if($response = getSuperAwesomeResponse()) { 
     print $response; 
     break; 
    } 

    // timeout after 60 seconds 
    if(($ts + 60) > time()) { 
     break; 
    } 

    sleep(1); 
} 

在客戶端,您只需發送某種ajax調用

+1

不要忘記在你的while循環中添加一個睡眠呼叫,否則會消耗大量的CPU時間。 – enricog 2012-04-03 07:22:57

+0

感謝您的評論。我完全忘了那一個。 :) – 2012-04-03 07:24:29

1

沒有,除非設備B正在運行某種(即接受傳入連接任何真正的軟件)的服務器。如果是這種情況,那麼您可以輕鬆向設備發出HTTP請求(例如,即使使用file_get_contents),或者擁有自己的自定義連接協議(使用sockets)。還有其他選項可以讓您使用相同的功能,但工作方式稍有不同。

如果設備沒有運行任何服務器,那麼您可以做的最好的事情是連續輪詢服務器以查看是否有任何命令。這更容易設置(服務器已經存在),但效率也不高。

+0

感謝您的評論。所以你的建議是做一個命令隊列,每次連接設備b給他的隊列頂部?你將如何實現這個隊列? – Tobrun 2012-04-03 07:14:40

+0

@ user1281750:如果您不想丟失任何命令,您肯定需要創建一個隊列,因爲您不確定何時/如果設備B將連接到它們以接收它們。您可以使用標準數組(array_push' /'array_pop')非常輕鬆地實現隊列。 – Jon 2012-04-03 07:28:54

1

設備B可以打開到服務器的客戶端連接並等待傳入​​數據。如果數據進入,設備B上運行的客戶端可能會回顯它。

PHP提供了訪問網絡套接字,看到http://www.php.net/manual/en/book.sockets.php

一些PHP示例代碼利用的LibEventZMQ,允許進入插座和隊列的更高層次:

事件驅動的服務器:

<?php 
// create base and event 
$base = event_base_new(); 
$event = event_new(); 

// Allocate a new context 
$context = new ZMQContext(); 

// Create sockets 
$rep = $context->getSocket(ZMQ::SOCKET_REP); 

// Connect the socket 
$rep->bind("tcp://127.0.0.1:5555"); 

// Get the stream descriptor 
$fd = $rep->getsockopt(ZMQ::SOCKOPT_FD); 

// Define event callback function 
$fnc = function ($fd, $events, $arg) { 
    static $msgs = 1; 
    echo "CALLBACK FIRED" . PHP_EOL; 
    if($arg[0]->getsockopt (ZMQ::SOCKOPT_EVENTS) & ZMQ::POLL_IN) { 
     echo "Got incoming data" . PHP_EOL; 
     var_dump ($arg[0]->recv()); 
     $arg[0]->send("Got msg $msgs"); 
     if($msgs++ >= 10) event_base_loopexit($arg[1]); 
    } 
}; 

// set event flags 
event_set($event, $fd, EV_READ | EV_PERSIST, $fnc, array($rep, $base)); 

// set event base 
event_base_set($event, $base); 

// enable event 
event_add($event); 

// start event loop 
event_base_loop($base); 

ZeroMQ客戶:

<?php 
// Create new queue object 
$queue = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REQ, "MySock1"); 
$queue->connect("tcp://127.0.0.1:5555"); 

// Assign socket 1 to the queue, send and receive 
var_dump($queue->send("hello there!")->recv()); 

SourceTalkVideo (~22:00)