2015-06-10 34 views
5

Muszę wykonać skomplikowane obliczenia między wysyłaniem wiadomości, ale pierwsza wiadomość jest wysyłana z sekundą po kompultowaniu. Jak mogę to natychmiast wysłać?Ratchet WebSocket - natychmiast wyślij wiadomość

<?php 

namespace AppBundle\WSServer; 

use Ratchet\MessageComponentInterface; 
use Ratchet\ConnectionInterface; 

class CommandManager implements MessageComponentInterface { 

    public function onOpen(ConnectionInterface $conn) { 
     //... 
    } 

    public function onClose(ConnectionInterface $connection) { 
     //... 
    } 

    public function onMessage(ConnectionInterface $connection, $msg) { 
     //... 
     $connection->send('{"command":"someString","data":"data"}'); 

     //...complicated compulting 
     sleep(10); 

     //send result 
     $connection->send('{"command":"someString","data":"data"}'); 
     return; 
    } 
} 

Uruchomienie serwera:

$server = IoServer::factory(
       new HttpServer(
        new WsServer(
         $ws_manager 
       ) 
      ), $port 
); 
+0

Można użyć EventLoop który uruchamia każdą milisekundę, a swoją kolejkę komunikatów do wysłania. – MarshallOfSound

+0

To fajny pomysł, ale myślę, że nie jest to optymalne rozwiązanie (wiele iteracji, które nic nie robią). Niestety nie znam lepszego sposobu. – Redkrytos

+0

Tak, to było coś w rodzaju ostatniej sugestii. Nie obejść niektórych głównych części Ratchet. Przypuszczam, że mógłbyś użyć symfonii, aby uruchomić nowy proces roboczy do komputerów? – MarshallOfSound

Odpowiedz

1

send ostatecznie trafia do reagowania na EventLoop który wysyła komunikat asynchronicznie kiedy jest „gotowy”. W międzyczasie rezygnuje z wykonania, a następnie skrypty wykonują obliczenia. W tym czasie bufor wyśle ​​twoje pierwsze i drugie wiadomości. Aby tego uniknąć można powiedzieć obliczenia wykonać na EventLoop jako kleszcza po obecne bufory są osuszone:

class CommandMessage implements \Ratchet\MessageComponentInterface { 
    private $loop; 
    public function __construct(\React\EventLoop\LoopInterface $loop) { 
     $this->loop = $loop; 
    } 

    public function onMessage(\Ratchet\ConnectionInterface $conn, $msg) { 
     $conn->send('{"command":"someString","data":"data"}'); 

     $this->loop->nextTick(function() use ($conn) { 
      sleep(10); 

      $conn->send('{"command":"someString","data":"data"}'); 
     }); 
    } 
} 

$loop = \React\EventLoop\Factory::create(); 

$socket = new \React\Socket\Server($loop); 
$socket->listen($port, '0.0.0.0'); 

$server = new \Ratchet\IoServer(
    new HttpServer(
     new WsServer(
      new CommandManager($loop) 
     ) 
    ), 
    $socket, 
    $loop 
); 

$server->run();