onClose hook is triggered upon is CloseConnection command (server side) now.  Allowing applications to handle any final executions before the connection is closed.
Updated some API documentation.
This commit is contained in:
Chris Boden 2011-11-08 11:04:30 -05:00
parent 9a35690e98
commit 15ec375405
7 changed files with 48 additions and 31 deletions

View File

@ -2,6 +2,9 @@
namespace Ratchet\Command\Action; namespace Ratchet\Command\Action;
use Ratchet\Command\ActionTemplate; use Ratchet\Command\ActionTemplate;
use Ratchet\SocketObserver; use Ratchet\SocketObserver;
use Ratchet\SocketInterface;
use Ratchet\Command\CommandInterface;
use Ratchet\Command\Composite;
/** /**
* Close the connection to the sockets passed in the constructor * Close the connection to the sockets passed in the constructor
@ -9,8 +12,21 @@ use Ratchet\SocketObserver;
class CloseConnection extends ActionTemplate { class CloseConnection extends ActionTemplate {
function execute(SocketObserver $scope = null) { function execute(SocketObserver $scope = null) {
$ret = $scope->onClose($this->getSocket()); $ret = $scope->onClose($this->getSocket());
$this->getSocket()->close();
return $ret; if ($ret instanceof CommandInterface) {
$comp = new Composite;
$comp->enqueue($ret);
$rt = new Runtime($this->getSocket());
$rt->setCommand(function(SocketInterface $socket, SocketObserver $scope) {
$socket->close();
});
$comp->enqueue($rt);
return $comp;
}
$this->getSocket()->close();
} }
} }

View File

@ -10,7 +10,7 @@ class Runtime extends ActionTemplate {
protected $_command = null; protected $_command = null;
/** /**
* Your closure should accept a single \Ratchet\SocketInterface parameter and return a CommandInterface or NULL * Your closure should accept two parameters (\Ratchet\SocketInterface, \Ratchet\SocketObserver) parameter and return a CommandInterface or NULL
* @param Closure Your closure/lambda to execute when the time comes * @param Closure Your closure/lambda to execute when the time comes
*/ */
public function setCommand(\Closure $callback) { public function setCommand(\Closure $callback) {
@ -18,6 +18,6 @@ class Runtime extends ActionTemplate {
} }
public function execute(SocketObserver $scope = null) { public function execute(SocketObserver $scope = null) {
return call_user_func($this->_command, $this->getSocket()); return call_user_func($this->_command, $this->getSocket(), $scope);
} }
} }

View File

@ -2,6 +2,9 @@
namespace Ratchet\Command; namespace Ratchet\Command;
use Ratchet\SocketInterface; use Ratchet\SocketInterface;
/**
* A factory pattern class to easily create all the things in the Ratchet\Command interface
*/
class Factory { class Factory {
protected $_paths = array(); protected $_paths = array();

View File

@ -14,27 +14,27 @@ use Ratchet\Protocol\WebSocket\Util\HTTP;
* This is a mediator between the Server and your application to handle real-time messaging through a web browser * This is a mediator between the Server and your application to handle real-time messaging through a web browser
* @link http://ca.php.net/manual/en/ref.http.php * @link http://ca.php.net/manual/en/ref.http.php
* @todo Make sure this works both ways (client/server) as stack needs to exist on client for framing * @todo Make sure this works both ways (client/server) as stack needs to exist on client for framing
* @todo Make sure all SendMessage Commands are framed, not just ones received from onRecv
* @todo Learn about closing the socket. A message has to be sent prior to closing - does the message get sent onClose event or CloseConnection command? * @todo Learn about closing the socket. A message has to be sent prior to closing - does the message get sent onClose event or CloseConnection command?
* @todo Consider cheating the application...don't call _app::onOpen until handshake is complete - only issue is sending headers/cookies
*/ */
class WebSocket implements ProtocolInterface { class WebSocket implements ProtocolInterface {
/**
* @var Ratchet\Command\Factory
*/
protected $_factory;
/** /**
* Lookup for connected clients * Lookup for connected clients
* @type SplObjectStorage * @var SplObjectStorage
*/ */
protected $_clients; protected $_clients;
/** /**
* Decorated application * Decorated application
* @type Ratchet\SocketObserver * @var Ratchet\SocketObserver
*/ */
protected $_app; protected $_app;
/**
* @var Ratchet\Command\Factory
*/
protected $_factory;
/** /**
* @internal * @internal
*/ */
@ -107,6 +107,12 @@ class WebSocket implements ProtocolInterface {
public function onClose(SocketInterface $conn) { public function onClose(SocketInterface $conn) {
$cmds = $this->prepareCommand($this->_app->onClose($conn)); $cmds = $this->prepareCommand($this->_app->onClose($conn));
// $cmds = new Composite if null
// $cmds->enqueue($this->_factory->newCommand('SendMessage', $conn)->setMessage(
// WebSocket close handshake, depending on version!
//));
unset($this->_clients[$conn]); unset($this->_clients[$conn]);
return $cmds; return $cmds;
} }
@ -139,7 +145,7 @@ class WebSocket implements ProtocolInterface {
/** /**
* @param array of HTTP headers * @param array of HTTP headers
* @return Version\VersionInterface * @return WebSocket\Version\VersionInterface
*/ */
protected function getVersion($message) { protected function getVersion($message) {
$headers = HTTP::getHeaders($message); $headers = HTTP::getHeaders($message);
@ -156,7 +162,7 @@ class WebSocket implements ProtocolInterface {
} }
/** /**
* @return Version\VersionInterface * @return WebSocket\Version\VersionInterface
*/ */
protected function versionFactory($version) { protected function versionFactory($version) {
if (null === $this->_versions[$version]) { if (null === $this->_versions[$version]) {

View File

@ -1,13 +1,9 @@
<?php <?php
namespace Ratchet\Command; namespace Ratchet\Protocol\WebSocket\Command\Action;
use Ratchet\SocketInterface; use Ratchet\Command\ActionTemplate;
use Ratchet\Command\ActionInterface;
use Ratchet\SocketObserver; use Ratchet\SocketObserver;
class Ping implements ActionInterface { class Ping extends ActionTemplate {
public function __construct(SocketInterface $socket) {
}
public function execute(SocketObserver $scope = null) { public function execute(SocketObserver $scope = null) {
} }
} }

View File

@ -1,13 +1,9 @@
<?php <?php
namespace Ratchet\Command; namespace Ratchet\Protocol\WebSocket\Command\Action;
use Ratchet\SocketInterface; use Ratchet\Command\ActionTemplate;
use Ratchet\Command\ActionInterface;
use Ratchet\SocketObserver; use Ratchet\SocketObserver;
class Pong implements ActionInterface { class Pong extends ActionTemplate {
public function __construct(SocketInterface $socket) {
}
public function execute(SocketObserver $scope = null) { public function execute(SocketObserver $scope = null) {
} }
} }

View File

@ -8,7 +8,7 @@ interface SocketObserver {
/** /**
* When a new connection is opened it will be passed to this method * When a new connection is opened it will be passed to this method
* @param SocketInterface * @param SocketInterface
* @return Command\CommandInterface|NULL * @return Ratchet\Command\CommandInterface|null
*/ */
function onOpen(SocketInterface $conn); function onOpen(SocketInterface $conn);
@ -16,14 +16,14 @@ interface SocketObserver {
* Triggered when a client sends data through the socket * Triggered when a client sends data through the socket
* @param SocketInterface * @param SocketInterface
* @param string * @param string
* @return Command\CommandInterface|NULL * @return Ratchet\Command\CommandInterface|null
*/ */
function onRecv(SocketInterface $from, $msg); function onRecv(SocketInterface $from, $msg);
/** /**
* This is called just before the connection is closed * This is called just before the connection is closed
* @param SocketInterface * @param SocketInterface
* @return Command\CommandInterface|NULL * @return Ratchet\Command\CommandInterface|null
* @todo This is triggered if the client or server terminates the connection; consider a new onDisconnect if server triggered * @todo This is triggered if the client or server terminates the connection; consider a new onDisconnect if server triggered
*/ */
function onClose(SocketInterface $conn); function onClose(SocketInterface $conn);