Refactoring
Refactored Command/Composite pattern, now as expected Server recursively executes commands Above changes fixed issues of server/client not being notified on forced disconnects
This commit is contained in:
parent
66e656ec63
commit
d880d29729
lib/Ratchet
@ -1,12 +1,14 @@
|
||||
<?php
|
||||
namespace Ratchet\Command\Action;
|
||||
use Ratchet\Command\CommandInterface;
|
||||
use Ratchet\Command\ActionInterface;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
/**
|
||||
* Close the connection to the sockets passed in the constructor
|
||||
* @todo The server does not seem to be notified when a resource is closed by this class...
|
||||
*/
|
||||
class CloseConnection implements CommandInterface {
|
||||
class CloseConnection implements ActionInterface {
|
||||
/**
|
||||
* @var SocketInterface
|
||||
*/
|
||||
@ -16,7 +18,10 @@ class CloseConnection implements CommandInterface {
|
||||
$this->_socket = $socket;
|
||||
}
|
||||
|
||||
function execute() {
|
||||
function execute(SocketObserver $scope = null) {
|
||||
$ret = $scope->onClose($this->_socket);
|
||||
$this->_socket->close();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
<?php
|
||||
namespace Ratchet\Command\Action;
|
||||
use Ratchet\Command\CommandInterface;
|
||||
use Ratchet\Command\ActionInterface;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
/**
|
||||
* Null pattern - execution does nothing, something needs to be passed back though
|
||||
*/
|
||||
class Null implements CommandInterface {
|
||||
class Null implements ActionInterface {
|
||||
public function __construct(SocketInterface $socket) {
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
public function execute(SocketObserver $scope = null) {
|
||||
}
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
<?php
|
||||
namespace Ratchet\Command\Action;
|
||||
use Ratchet\Command\CommandInterface;
|
||||
use Ratchet\Command\ActionInterface;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
class Runtime implements CommandInterface {
|
||||
class Runtime implements ActionInterface {
|
||||
/**
|
||||
* @var SocketInterface
|
||||
*/
|
||||
@ -26,7 +27,7 @@ class Runtime implements CommandInterface {
|
||||
$this->_command = $callback;
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
public function execute(SocketObserver $scope = null) {
|
||||
return call_user_func($this->_command, $socket);
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
<?php
|
||||
namespace Ratchet\Command\Action;
|
||||
use Ratchet\Command\CommandInterface;
|
||||
use Ratchet\Command\ActionInterface;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
/**
|
||||
* Send text back to the client end of the socket(s)
|
||||
*/
|
||||
class SendMessage implements CommandInterface {
|
||||
class SendMessage implements ActionInterface {
|
||||
/**
|
||||
* @var SocketInterface
|
||||
*/
|
||||
@ -42,7 +43,7 @@ class SendMessage implements CommandInterface {
|
||||
/**
|
||||
* @throws \UnexpectedValueException if a message was not set with setMessage()
|
||||
*/
|
||||
public function execute() {
|
||||
public function execute(SocketObserver $scope = null) {
|
||||
if (empty($this->_message)) {
|
||||
throw new \UnexpectedValueException("Message is empty");
|
||||
}
|
||||
|
11
lib/Ratchet/Command/ActionInterface.php
Normal file
11
lib/Ratchet/Command/ActionInterface.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace Ratchet\Command;
|
||||
use Ratchet\SocketInterface;
|
||||
|
||||
interface ActionInterface extends CommandInterface {
|
||||
/**
|
||||
* Pass the Sockets to execute the command on
|
||||
* @param Ratchet\SocketInterface
|
||||
*/
|
||||
function __construct(SocketInterface $socket);
|
||||
}
|
@ -1,20 +1,14 @@
|
||||
<?php
|
||||
namespace Ratchet\Command;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
/**
|
||||
* Socket implementation of the Command Pattern
|
||||
* User created applications are to return a Command to the server for execution
|
||||
*/
|
||||
interface CommandInterface {
|
||||
/**
|
||||
* Pass the Sockets to execute the command on
|
||||
* @param Ratchet\SocketInterface
|
||||
*/
|
||||
function __construct(SocketInterface $socket);
|
||||
|
||||
/**
|
||||
* The Server class will call the execution
|
||||
*/
|
||||
function execute();
|
||||
function execute(SocketObserver $scope = null);
|
||||
}
|
@ -1,17 +1,35 @@
|
||||
<?php
|
||||
namespace Ratchet\Command;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
class Composite extends \SplQueue {
|
||||
class Composite extends \SplQueue implements CommandInterface {
|
||||
public function enqueue(CommandInterface $command) {
|
||||
return parent::enqueue($command);
|
||||
if ($command instanceof Composite) {
|
||||
foreach ($command as $cmd) {
|
||||
$this->enqueue($cmd);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent::enqueue($command);
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
public function execute(SocketObserver $scope = null) {
|
||||
$this->setIteratorMode(static::IT_MODE_DELETE);
|
||||
|
||||
$recursive = new self;
|
||||
|
||||
foreach ($this as $command) {
|
||||
$command->execute();
|
||||
$ret = $command->execute($scope);
|
||||
|
||||
if ($ret instanceof CommandInterface) {
|
||||
$recursive->enqueue($ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($recursive) > 0) {
|
||||
return $recursive;
|
||||
}
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ class WebSocket implements ProtocolInterface {
|
||||
}
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
$cmd = new Composite;
|
||||
$close = new \Ratchet\Command\Close($from);
|
||||
$close = new \Ratchet\Command\Action\CloseConnection($from); // This is to change to Disconnect (proper protocol close)
|
||||
$cmd->enqueue($close);
|
||||
|
||||
return $cmd;
|
||||
|
20
lib/Ratchet/Protocol/WebSocket/Command/Action/Disconnect.php
Normal file
20
lib/Ratchet/Protocol/WebSocket/Command/Action/Disconnect.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace Ratchet\Protocol\WebSocket\Command\Action;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\Command\Action\SendMessage;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
class Disconnect extends SendMessage {
|
||||
protected $_code = 1000;
|
||||
|
||||
public function setStatusCode($code) {
|
||||
$this->_code = (int)$code;
|
||||
|
||||
// re-do message based on code
|
||||
}
|
||||
|
||||
public function execute(SocketObserver $scope = null) {
|
||||
parent::execute();
|
||||
$this->_socket->close();
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
<?php
|
||||
namespace Ratchet\Command;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\Command\CommandInterface;
|
||||
use Ratchet\Command\ActionInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
class Ping implements CommandInterface {
|
||||
class Ping implements ActionInterface {
|
||||
public function __construct(SocketInterface $socket) {
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
public function execute(SocketObserver $scope = null) {
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
<?php
|
||||
namespace Ratchet\Command;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\Command\CommandInterface;
|
||||
use Ratchet\Command\ActionInterface;
|
||||
use Ratchet\SocketObserver;
|
||||
|
||||
class Pong implements CommandInterface {
|
||||
class Pong implements ActionInterface {
|
||||
public function __construct(SocketInterface $socket) {
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
public function execute(SocketObserver $scope = null) {
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ use Ratchet\Server\Aggregator;
|
||||
use Ratchet\Protocol\ProtocolInterface;
|
||||
use Ratchet\Logging\LoggerInterface;
|
||||
use Ratchet\Logging\NullLogger;
|
||||
use Ratchet\Command\Composite;
|
||||
use Ratchet\Command\CommandInterface;
|
||||
|
||||
/**
|
||||
* Creates an open-ended socket to listen on a port for incomming connections. Events are delegated through this to attached applications
|
||||
@ -72,6 +72,7 @@ class Server implements SocketObserver, \IteratorAggregate {
|
||||
* @throws Exception
|
||||
* @todo Validate address. Use socket_get_option, if AF_INET must be IP, if AF_UNIX must be path
|
||||
* @todo Should I make handling open/close/msg an application?
|
||||
* @todo Consider making the 4kb listener changable
|
||||
*/
|
||||
public function run($address = '127.0.0.1', $port = 1025) {
|
||||
set_time_limit(0);
|
||||
@ -107,8 +108,8 @@ class Server implements SocketObserver, \IteratorAggregate {
|
||||
}
|
||||
}
|
||||
|
||||
if ($res instanceof Composite) {
|
||||
$res->execute();
|
||||
while ($res instanceof CommandInterface) {
|
||||
$res = $res->execute($this);
|
||||
}
|
||||
}
|
||||
} catch (Exception $se) {
|
||||
|
Loading…
Reference in New Issue
Block a user