From e1c7ce361fe1a61cbade4aa19b133a261f914f29 Mon Sep 17 00:00:00 2001 From: Chris Boden Date: Tue, 31 Jan 2012 08:37:51 -0500 Subject: [PATCH] App -> Component Refactoring Updating namespacing and conventions as per ticket #1 --- .../Component/MessageComponentInterface.php | 14 +++++++++ src/Ratchet/Component/Server/App.php | 21 ++++++------- .../WAMP/{App.php => WAMPComponent.php} | 22 +++++++------- ...e.php => WAMPServerComponentInterface.php} | 2 +- .../{App.php => WebSocketComponent.php} | 30 +++++++++---------- ...ce.php => WebSocketComponentInterface.php} | 2 +- .../Command/{ => Action}/ActionInterface.php | 2 +- .../Command/{ => Action}/ActionTemplate.php | 2 +- .../Command/Action/CloseConnection.php | 1 - src/Ratchet/Resource/Command/Action/Null.php | 3 +- .../Resource/Command/Action/Runtime.php | 12 ++++++-- .../Resource/Command/Action/SendMessage.php | 2 +- .../Server/AppTest.php | 4 +-- .../WebSocket/Version/Hixie76Test.php | 0 .../WebSocket/Version/HyBi10Test.php | 0 .../WebSocket/Version/RFC6455/FrameTest.php | 0 .../Version/RFC6455/HandshakeVerifierTest.php | 0 .../WebSocket/Version/RFC6455Test.php | 0 .../Mock/{Application.php => Component.php} | 4 +-- vendor/.composer/ClassLoader.php | 2 ++ vendor/.composer/autoload.php | 22 ++++++++++++++ vendor/.composer/autoload_namespaces.php | 11 +++++++ vendor/.composer/installed.json | 22 ++++++++++++++ 23 files changed, 126 insertions(+), 52 deletions(-) create mode 100644 src/Ratchet/Component/MessageComponentInterface.php rename src/Ratchet/Component/WAMP/{App.php => WAMPComponent.php} (86%) rename src/Ratchet/Component/WAMP/{ServerInterface.php => WAMPServerComponentInterface.php} (98%) rename src/Ratchet/Component/WebSocket/{App.php => WebSocketComponent.php} (88%) rename src/Ratchet/Component/WebSocket/{WebSocketAppInterface.php => WebSocketComponentInterface.php} (89%) rename src/Ratchet/Resource/Command/{ => Action}/ActionInterface.php (90%) rename src/Ratchet/Resource/Command/{ => Action}/ActionTemplate.php (89%) rename tests/Ratchet/Tests/{Application => Component}/Server/AppTest.php (94%) rename tests/Ratchet/Tests/{Application => Component}/WebSocket/Version/Hixie76Test.php (100%) rename tests/Ratchet/Tests/{Application => Component}/WebSocket/Version/HyBi10Test.php (100%) rename tests/Ratchet/Tests/{Application => Component}/WebSocket/Version/RFC6455/FrameTest.php (100%) rename tests/Ratchet/Tests/{Application => Component}/WebSocket/Version/RFC6455/HandshakeVerifierTest.php (100%) rename tests/Ratchet/Tests/{Application => Component}/WebSocket/Version/RFC6455Test.php (100%) rename tests/Ratchet/Tests/Mock/{Application.php => Component.php} (89%) create mode 100644 vendor/.composer/ClassLoader.php create mode 100644 vendor/.composer/autoload.php create mode 100644 vendor/.composer/autoload_namespaces.php create mode 100644 vendor/.composer/installed.json diff --git a/src/Ratchet/Component/MessageComponentInterface.php b/src/Ratchet/Component/MessageComponentInterface.php new file mode 100644 index 0000000..10e9fea --- /dev/null +++ b/src/Ratchet/Component/MessageComponentInterface.php @@ -0,0 +1,14 @@ +_app = $application; + public function __construct(MessageComponentInterface $component) { + $this->_decorating = $component; } /** @@ -68,8 +67,6 @@ class App implements ComponentInterface { * @param mixed The address to listen for incoming connections on. "0.0.0.0" to listen from anywhere * @param int The port to listen to connections on (make sure to run as root if < 1000) * @throws Ratchet\Exception - * @todo Validate address. Use socket_get_option, if AF_INET must be IP, if AF_UNIX must be path - * @todo Consider making the 4kb listener changable */ public function run(SocketInterface $host, $address = '127.0.0.1', $port = 1025) { $this->_connections[$host->getResource()] = new Connection($host); @@ -156,17 +153,17 @@ class App implements ComponentInterface { $this->_resources[] = $new_connection->getSocket()->getResource(); $this->_connections[$new_connection->getSocket()->getResource()] = $new_connection; - return $this->_app->onOpen($new_connection); + return $this->_decorating->onOpen($new_connection); } public function onMessage(ConnectionInterface $from, $msg) { - return $this->_app->onMessage($from, $msg); + return $this->_decorating->onMessage($from, $msg); } public function onClose(ConnectionInterface $conn) { $resource = $conn->getSocket()->getResource(); - $cmd = $this->_app->onClose($conn); + $cmd = $this->_decorating->onClose($conn); unset($this->_connections[$resource], $this->_resources[array_search($resource, $this->_resources)]); @@ -174,6 +171,6 @@ class App implements ComponentInterface { } public function onError(ConnectionInterface $conn, \Exception $e) { - return $this->_app->onError($conn, $e); + return $this->_decorating->onError($conn, $e); } } \ No newline at end of file diff --git a/src/Ratchet/Component/WAMP/App.php b/src/Ratchet/Component/WAMP/WAMPComponent.php similarity index 86% rename from src/Ratchet/Component/WAMP/App.php rename to src/Ratchet/Component/WAMP/WAMPComponent.php index c26fd12..b437182 100644 --- a/src/Ratchet/Component/WAMP/App.php +++ b/src/Ratchet/Component/WAMP/WAMPComponent.php @@ -25,7 +25,7 @@ use Ratchet\Component\WAMP\Command\Action\Prefix; * @link http://www.tavendo.de/autobahn/protocol.html * @link https://raw.github.com/oberstet/Autobahn/master/lib/javascript/autobahn.js */ -class App implements WebSocketAppInterface { +class WAMPComponent implements WebSocketAppInterface { const MSG_WELCOME = 0; const MSG_PREFIX = 1; const MSG_CALL = 2; @@ -36,7 +36,7 @@ class App implements WebSocketAppInterface { const MSG_PUBLISH = 7; const MSG_EVENT = 8; - protected $_app; + protected $_decorating; /** * Any server to client prefixes are stored here @@ -78,7 +78,7 @@ class App implements WebSocketAppInterface { $wamp->addPrefix($conn, $curie, $uri, true); }; - return $this->_app->onOpen($conn); + return $this->_decorating->onOpen($conn); } /** @@ -105,19 +105,19 @@ class App implements WebSocketAppInterface { $json = $json[0]; } - $ret = $this->_app->onCall($from, $callID, $procURI, $json); + $ret = $this->_decorating->onCall($from, $callID, $procURI, $json); break; case static::MSG_SUBSCRIBE: - $ret = $this->_app->onSubscribe($from, $this->getUri($from, $json[1])); + $ret = $this->_decorating->onSubscribe($from, $this->getUri($from, $json[1])); break; case static::MSG_UNSUBSCRIBE: - $ret = $this->_app->onUnSubscribe($from, $this->getUri($from, $json[1])); + $ret = $this->_decorating->onUnSubscribe($from, $this->getUri($from, $json[1])); break; case static::MSG_PUBLISH: - $ret = $this->_app->onPublish($from, $this->getUri($from, $json[1]), $json[2]); + $ret = $this->_decorating->onPublish($from, $this->getUri($from, $json[1]), $json[2]); break; default: @@ -152,16 +152,16 @@ class App implements WebSocketAppInterface { return $stack; } - public function __construct(ServerInterface $app) { - $this->_app = $app; + public function __construct(WAMPServerComponentInterface $server_component) { + $this->_decorating = $server_component; $this->_msg_buffer = new Composite; } public function onClose(ConnectionInterface $conn) { - return $this->_app->onClose($conn); + return $this->_decorating->onClose($conn); } public function onError(ConnectionInterface $conn, \Exception $e) { - return $this->_app->onError($conn, $e); + return $this->_decorating->onError($conn, $e); } } \ No newline at end of file diff --git a/src/Ratchet/Component/WAMP/ServerInterface.php b/src/Ratchet/Component/WAMP/WAMPServerComponentInterface.php similarity index 98% rename from src/Ratchet/Component/WAMP/ServerInterface.php rename to src/Ratchet/Component/WAMP/WAMPServerComponentInterface.php index bf06563..48ebee6 100644 --- a/src/Ratchet/Component/WAMP/ServerInterface.php +++ b/src/Ratchet/Component/WAMP/WAMPServerComponentInterface.php @@ -7,7 +7,7 @@ use Ratchet\Resource\ConnectionInterface; * onMessage is replaced by various types of messages for this protocol (pub/sub or rpc) * @todo Thought: URI as class. Class has short and long version stored (if as prefix) */ -interface ServerInterface { +interface WAMPServerComponentInterface { /** * When a new connection is opened it will be passed to this method * @param Ratchet\Resource\Connection diff --git a/src/Ratchet/Component/WebSocket/App.php b/src/Ratchet/Component/WebSocket/WebSocketComponent.php similarity index 88% rename from src/Ratchet/Component/WebSocket/App.php rename to src/Ratchet/Component/WebSocket/WebSocketComponent.php index d6a0313..6b43541 100644 --- a/src/Ratchet/Component/WebSocket/App.php +++ b/src/Ratchet/Component/WebSocket/WebSocketComponent.php @@ -12,16 +12,14 @@ use Ratchet\Component\WebSocket\Guzzle\Http\Message\RequestFactory; * The adapter to handle WebSocket requests/responses * 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 - * @todo Make sure this works both ways (client/server) as stack needs to exist on client for framing - * @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 chaning this class to a State Pattern. If a WS App interface is passed use different state for additional methods used + * @link http://dev.w3.org/html5/websockets/ */ -class App implements ComponentInterface { +class WebSocketComponent implements ComponentInterface { /** - * Decorated application + * Decorated component * @var Ratchet\Component\ComponentInterface */ - protected $_app; + protected $_decorating; /** * Creates commands/composites instead of calling several classes manually @@ -42,16 +40,20 @@ class App implements ComponentInterface { protected $_mask_payload = false; /** + * For now, array_push accepted subprotocols to this array * @deprecated * @temporary */ public $accepted_subprotocols = array(); - public function __construct(ComponentInterface $app) { - $this->_app = $app; - $this->_factory = new Factory; + public function __construct(ComponentInterface $component) { + $this->_decorating = $component; + $this->_factory = new Factory; } + /** + * @{inheritdoc} + */ public function onOpen(ConnectionInterface $conn) { $conn->WebSocket = new \stdClass; $conn->WebSocket->handshake = false; @@ -60,8 +62,6 @@ class App implements ComponentInterface { /** * Do handshake, frame/unframe messages coming/going in stack - * @todo This needs some major refactoring - * @todo "Once the client's opening handshake has been sent, the client MUST wait for a response from the server before sending any further data." */ public function onMessage(ConnectionInterface $from, $msg) { if (true !== $from->WebSocket->handshake) { @@ -107,7 +107,7 @@ class App implements ComponentInterface { $comp = $this->_factory->newComposite(); $comp->enqueue($this->_factory->newCommand('SendMessage', $from)->setMessage($header)); - $comp->enqueue($this->prepareCommand($this->_app->onOpen($from, $msg))); // Need to send headers/handshake to application, let it have the cookies, etc + $comp->enqueue($this->prepareCommand($this->_decorating->onOpen($from, $msg))); // Need to send headers/handshake to application, let it have the cookies, etc return $comp; } @@ -136,7 +136,7 @@ class App implements ComponentInterface { } if ($from->WebSocket->message->isCoalesced()) { - $cmds = $this->prepareCommand($this->_app->onMessage($from, (string)$from->WebSocket->message)); + $cmds = $this->prepareCommand($this->_decorating->onMessage($from, (string)$from->WebSocket->message)); unset($from->WebSocket->message); return $cmds; @@ -144,14 +144,14 @@ class App implements ComponentInterface { } public function onClose(ConnectionInterface $conn) { - return $this->prepareCommand($this->_app->onClose($conn)); + return $this->prepareCommand($this->_decorating->onClose($conn)); } /** * @todo Shouldn't I be using prepareCommand() on the return? look into this */ public function onError(ConnectionInterface $conn, \Exception $e) { - return $this->_app->onError($conn, $e); + return $this->_decorating->onError($conn, $e); } /** diff --git a/src/Ratchet/Component/WebSocket/WebSocketAppInterface.php b/src/Ratchet/Component/WebSocket/WebSocketComponentInterface.php similarity index 89% rename from src/Ratchet/Component/WebSocket/WebSocketAppInterface.php rename to src/Ratchet/Component/WebSocket/WebSocketComponentInterface.php index 4770849..80e045b 100644 --- a/src/Ratchet/Component/WebSocket/WebSocketAppInterface.php +++ b/src/Ratchet/Component/WebSocket/WebSocketComponentInterface.php @@ -7,7 +7,7 @@ use Ratchet\Component\ComponentInterface; * @todo WebSocket checks if instanceof AppInterface, if so uses getSubProtocol() when doing handshake * @todo Pick a better name for this... */ -interface WebSocketAppInterface extends ComponentInterface { +interface WebSocketComponentInterface extends ComponentInterface { /** * Currently instead of this, I'm setting header in the Connection object passed around...not sure which I like more * @param string diff --git a/src/Ratchet/Resource/Command/ActionInterface.php b/src/Ratchet/Resource/Command/Action/ActionInterface.php similarity index 90% rename from src/Ratchet/Resource/Command/ActionInterface.php rename to src/Ratchet/Resource/Command/Action/ActionInterface.php index 4c196f4..512c42c 100644 --- a/src/Ratchet/Resource/Command/ActionInterface.php +++ b/src/Ratchet/Resource/Command/Action/ActionInterface.php @@ -1,5 +1,5 @@ _command = $callback; } + /** + * @{inheritdoc} + */ public function execute(ComponentInterface $scope = null) { - return call_user_func($this->_command, $this->getConnection(), $scope); + $cmd = $this->_command; + + return $cmd($this->getConnection(), $scope); } } \ No newline at end of file diff --git a/src/Ratchet/Resource/Command/Action/SendMessage.php b/src/Ratchet/Resource/Command/Action/SendMessage.php index de4cc24..8a9bc84 100644 --- a/src/Ratchet/Resource/Command/Action/SendMessage.php +++ b/src/Ratchet/Resource/Command/Action/SendMessage.php @@ -1,6 +1,5 @@ _app = new TestApp; $this->_server = new ServerApp($this->_app); - $ref = new \ReflectionClass('\Ratchet\Component\Server\App'); + $ref = new \ReflectionClass('\\Ratchet\\Component\\Server\\App'); $prop = $ref->getProperty('_run'); $prop->setAccessible(true); $prop->setValue($this->_server, false); diff --git a/tests/Ratchet/Tests/Application/WebSocket/Version/Hixie76Test.php b/tests/Ratchet/Tests/Component/WebSocket/Version/Hixie76Test.php similarity index 100% rename from tests/Ratchet/Tests/Application/WebSocket/Version/Hixie76Test.php rename to tests/Ratchet/Tests/Component/WebSocket/Version/Hixie76Test.php diff --git a/tests/Ratchet/Tests/Application/WebSocket/Version/HyBi10Test.php b/tests/Ratchet/Tests/Component/WebSocket/Version/HyBi10Test.php similarity index 100% rename from tests/Ratchet/Tests/Application/WebSocket/Version/HyBi10Test.php rename to tests/Ratchet/Tests/Component/WebSocket/Version/HyBi10Test.php diff --git a/tests/Ratchet/Tests/Application/WebSocket/Version/RFC6455/FrameTest.php b/tests/Ratchet/Tests/Component/WebSocket/Version/RFC6455/FrameTest.php similarity index 100% rename from tests/Ratchet/Tests/Application/WebSocket/Version/RFC6455/FrameTest.php rename to tests/Ratchet/Tests/Component/WebSocket/Version/RFC6455/FrameTest.php diff --git a/tests/Ratchet/Tests/Application/WebSocket/Version/RFC6455/HandshakeVerifierTest.php b/tests/Ratchet/Tests/Component/WebSocket/Version/RFC6455/HandshakeVerifierTest.php similarity index 100% rename from tests/Ratchet/Tests/Application/WebSocket/Version/RFC6455/HandshakeVerifierTest.php rename to tests/Ratchet/Tests/Component/WebSocket/Version/RFC6455/HandshakeVerifierTest.php diff --git a/tests/Ratchet/Tests/Application/WebSocket/Version/RFC6455Test.php b/tests/Ratchet/Tests/Component/WebSocket/Version/RFC6455Test.php similarity index 100% rename from tests/Ratchet/Tests/Application/WebSocket/Version/RFC6455Test.php rename to tests/Ratchet/Tests/Component/WebSocket/Version/RFC6455Test.php diff --git a/tests/Ratchet/Tests/Mock/Application.php b/tests/Ratchet/Tests/Mock/Component.php similarity index 89% rename from tests/Ratchet/Tests/Mock/Application.php rename to tests/Ratchet/Tests/Mock/Component.php index 5cb5b61..023cc8d 100644 --- a/tests/Ratchet/Tests/Mock/Application.php +++ b/tests/Ratchet/Tests/Mock/Component.php @@ -1,10 +1,10 @@ prefixes; } public function getFallbackDirs() { return $this->fallbackDirs; } public function add($prefix, $paths) { if (!$prefix) { $this->fallbackDirs = (array) $paths; return; } if (isset($this->prefixes[$prefix])) { $this->prefixes[$prefix] = array_merge( $this->prefixes[$prefix], (array) $paths ); } else { $this->prefixes[$prefix] = (array) $paths; } } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; return true; } } public function findFile($class) { if ('\\' == $class[0]) { $class = substr($class, 1); } if (false !== $pos = strrpos($class, '\\')) { $classPath = DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)); $className = substr($class, $pos + 1); } else { $classPath = null; $className = $class; } $classPath .= DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; foreach ($this->prefixes as $prefix => $dirs) { foreach ($dirs as $dir) { if (0 === strpos($class, $prefix)) { if (file_exists($dir . $classPath)) { return $dir . $classPath; } } } } foreach ($this->fallbackDirs as $dir) { if (file_exists($dir . $classPath)) { return $dir . $classPath; } } } } \ No newline at end of file diff --git a/vendor/.composer/autoload.php b/vendor/.composer/autoload.php new file mode 100644 index 0000000..3f20144 --- /dev/null +++ b/vendor/.composer/autoload.php @@ -0,0 +1,22 @@ + $path) { + $loader->add($namespace, $path); + } + + $loader->register(); + + return $loader; +}; + +return $__composer_autoload_init(); \ No newline at end of file diff --git a/vendor/.composer/autoload_namespaces.php b/vendor/.composer/autoload_namespaces.php new file mode 100644 index 0000000..1481677 --- /dev/null +++ b/vendor/.composer/autoload_namespaces.php @@ -0,0 +1,11 @@ + dirname($vendorDir) . '/tests', + 'Ratchet' => dirname($vendorDir) . '/lib', + 'Guzzle' => $vendorDir . '/guzzle/src', +); diff --git a/vendor/.composer/installed.json b/vendor/.composer/installed.json new file mode 100644 index 0000000..11ef412 --- /dev/null +++ b/vendor/.composer/installed.json @@ -0,0 +1,22 @@ +[ + { + "name": "guzzle", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/guzzle\/guzzle.git", + "reference": "ac64abc2c05b921efc4623379c1674a282475ae5" + }, + "type": "library", + "names": [ + "guzzle" + ], + "installation-source": "source", + "autoload": { + "psr-0": { + "Guzzle": "src" + } + } + } +] \ No newline at end of file