WebSocket declutter
Removed Client class and lookup from WebSocket app. WebSocket doesn't need a collection of connections as it's a messaging intermediary. Data is saved/attached to the specific connection as needed and leaves no state behind.
This commit is contained in:
parent
f3c7dd4d7f
commit
b641887b0e
@ -7,8 +7,6 @@ use Ratchet\Resource\Command\CommandInterface;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an open-ended socket to listen on a port for incomming connections. Events are delegated through this to attached applications
|
* Creates an open-ended socket to listen on a port for incomming connections. Events are delegated through this to attached applications
|
||||||
* @todo Consider using _connections as master reference and passing iterator_to_array(_connections) to socket_select
|
|
||||||
* @todo Currently passing Socket object down the decorated chain - should be sending reference to it instead; Receivers do not interact with the Socket directly, they do so through the Command pattern
|
|
||||||
* @todo With all these options for the server I should probably use a DIC
|
* @todo With all these options for the server I should probably use a DIC
|
||||||
*/
|
*/
|
||||||
class App implements ApplicationInterface {
|
class App implements ApplicationInterface {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Ratchet\Application\WebSocket;
|
namespace Ratchet\Application\WebSocket;
|
||||||
use Ratchet\Application\WebSocket\Client;
|
|
||||||
use Ratchet\Application\WebSocket\VersionInterface;
|
|
||||||
use Ratchet\Application\ApplicationInterface;
|
use Ratchet\Application\ApplicationInterface;
|
||||||
use Ratchet\Application\ConfiguratorInterface;
|
use Ratchet\Application\ConfiguratorInterface;
|
||||||
use Ratchet\Resource\Connection;
|
use Ratchet\Resource\Connection;
|
||||||
@ -13,23 +11,16 @@ use Ratchet\Application\WebSocket\Util\HTTP;
|
|||||||
/**
|
/**
|
||||||
* The adapter to handle WebSocket requests/responses
|
* 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
|
* This is a mediator between the Server and your application to handle real-time messaging through a web browser
|
||||||
|
* Sets 2 parameters on a Connection: handhsake_complete (bool) and websocket_version (Version\VersionInterface)
|
||||||
* @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 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
|
|
||||||
* @todo Consider chaning this class to a State Pattern. If a ObserverInterface is passed in __construct, do what is there now. If it's an AppInterface change behaviour of socket interaction (onOpen, handshake, etc)
|
* @todo Consider chaning this class to a State Pattern. If a ObserverInterface is passed in __construct, do what is there now. If it's an AppInterface change behaviour of socket interaction (onOpen, handshake, etc)
|
||||||
* @todo Change namespace to Ratchet\Application\WebSocket\Adapter
|
|
||||||
*/
|
*/
|
||||||
class App implements ApplicationInterface, ConfiguratorInterface {
|
class App implements ApplicationInterface, ConfiguratorInterface {
|
||||||
/**
|
|
||||||
* Lookup for connected clients
|
|
||||||
* @var SplObjectStorage
|
|
||||||
*/
|
|
||||||
protected $_clients;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorated application
|
* Decorated application
|
||||||
* @var Ratchet\ObserverInterface
|
* @var Ratchet\Application\ApplicationInterface
|
||||||
*/
|
*/
|
||||||
protected $_app;
|
protected $_app;
|
||||||
|
|
||||||
@ -39,6 +30,7 @@ class App implements ApplicationInterface, ConfiguratorInterface {
|
|||||||
protected $_factory;
|
protected $_factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Singleton* instances of protocol version classes
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
protected $_versions = array(
|
protected $_versions = array(
|
||||||
@ -51,7 +43,6 @@ class App implements ApplicationInterface, ConfiguratorInterface {
|
|||||||
throw new \UnexpectedValueException("WebSocket requires an application to run off of");
|
throw new \UnexpectedValueException("WebSocket requires an application to run off of");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_clients = new \SplObjectStorage;
|
|
||||||
$this->_app = $app;
|
$this->_app = $app;
|
||||||
$this->_factory = new Factory;
|
$this->_factory = new Factory;
|
||||||
}
|
}
|
||||||
@ -71,13 +62,17 @@ class App implements ApplicationInterface, ConfiguratorInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onOpen(Connection $conn) {
|
public function onOpen(Connection $conn) {
|
||||||
$this->_clients[$conn] = new Client;
|
$conn->handshake_complete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onRecv(Connection $from, $msg) {
|
public function onRecv(Connection $from, $msg) {
|
||||||
$client = $this->_clients[$from];
|
if (true !== $from->handshake_complete) {
|
||||||
if (true !== $client->isHandshakeComplete()) {
|
|
||||||
$response = $client->setVersion($this->getVersion($msg))->doHandshake($msg);
|
// need buffer checks in here
|
||||||
|
|
||||||
|
$from->websocket_version = $this->getVersion($msg);
|
||||||
|
$response = $from->websocket_version->handshake($msg);
|
||||||
|
$from->handshake_complete = true;
|
||||||
|
|
||||||
if (is_array($response)) {
|
if (is_array($response)) {
|
||||||
$header = '';
|
$header = '';
|
||||||
@ -100,25 +95,18 @@ class App implements ApplicationInterface, ConfiguratorInterface {
|
|||||||
return $comp;
|
return $comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
$msg = $client->getVersion()->unframe($msg);
|
// buffer!
|
||||||
|
|
||||||
|
$msg = $from->websocket_version->unframe($msg);
|
||||||
if (is_array($msg)) { // temporary
|
if (is_array($msg)) { // temporary
|
||||||
$msg = $msg['payload'];
|
$msg = $msg['payload'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$cmds = $this->_app->onRecv($from, $msg);
|
return $this->prepareCommand($this->_app->onRecv($from, $msg));
|
||||||
return $this->prepareCommand($cmds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onClose(Connection $conn) {
|
public function onClose(Connection $conn) {
|
||||||
$cmds = $this->prepareCommand($this->_app->onClose($conn));
|
return $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]);
|
|
||||||
return $cmds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onError(Connection $conn, \Exception $e) {
|
public function onError(Connection $conn, \Exception $e) {
|
||||||
@ -138,7 +126,7 @@ class App implements ApplicationInterface, ConfiguratorInterface {
|
|||||||
*/
|
*/
|
||||||
protected function prepareCommand(CommandInterface $command = null) {
|
protected function prepareCommand(CommandInterface $command = null) {
|
||||||
if ($command instanceof SendMessage) {
|
if ($command instanceof SendMessage) {
|
||||||
$version = $this->_clients[$command->getConnection()]->getVersion();
|
$version = $command->getConnection()->websocket_version;
|
||||||
return $command->setMessage($version->frame($command->getMessage()));
|
return $command->setMessage($version->frame($command->getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\Application\WebSocket;
|
|
||||||
use Ratchet\Application\WebSocket\Version\VersionInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A representation of a Socket connection of the user on the other end of the socket
|
|
||||||
* @todo Replace this with Resource\Connection\ConnectionInterface
|
|
||||||
*/
|
|
||||||
class Client {
|
|
||||||
/**
|
|
||||||
* @var Ratchet\Application\WebSocket\Version\VersionInterface
|
|
||||||
*/
|
|
||||||
protected $_version = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
protected $_hands_shook = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Version\VersionInterface
|
|
||||||
* @return Client
|
|
||||||
*/
|
|
||||||
public function setVersion(VersionInterface $version) {
|
|
||||||
$this->_version = $version;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Version\VersionInterface
|
|
||||||
*/
|
|
||||||
public function getVersion() {
|
|
||||||
return $this->_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string
|
|
||||||
* @return array|string
|
|
||||||
*/
|
|
||||||
public function doHandshake($headers) {
|
|
||||||
$this->_hands_shook = true;
|
|
||||||
|
|
||||||
return $this->_version->handshake($headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isHandshakeComplete() {
|
|
||||||
return $this->_hands_shook;
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,6 +29,7 @@ class Connection {
|
|||||||
* Anyway, if you're here, it's not recommended you use this/directly interact with the socket in your App...
|
* Anyway, if you're here, it's not recommended you use this/directly interact with the socket in your App...
|
||||||
* The command pattern (which is fully flexible, see Runtime) is the safest, desired way to interact with the socket(s).
|
* The command pattern (which is fully flexible, see Runtime) is the safest, desired way to interact with the socket(s).
|
||||||
* @return Ratchet\SocketInterface
|
* @return Ratchet\SocketInterface
|
||||||
|
* @todo Figure out a better way to match Socket/Connection in Application and Commands
|
||||||
*/
|
*/
|
||||||
public function getSocket() {
|
public function getSocket() {
|
||||||
return $this->_socket;
|
return $this->_socket;
|
||||||
|
Loading…
Reference in New Issue
Block a user