From cfd22179b332356b37e461f752ff2d64630089a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 26 Oct 2016 14:50:59 +0200 Subject: [PATCH] Documentation for ServerInterface --- README.md | 123 ++++++++++++++++++++++++++++++++++++---- src/Server.php | 25 +++++++- src/ServerInterface.php | 81 +++++++++++++++++++++++++- 3 files changed, 217 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 837bf113..2fc31025 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,12 @@ and [`Stream`](https://github.com/reactphp/stream) components. * [Quickstart example](#quickstart-example) * [Usage](#usage) + * [ServerInterface](#serverinterface) + * [connection event](#connection-event) + * [error event](#error-event) + * [listen()](#listen) + * [getPort()](#getport) + * [shutdown()](#shutdown) * [Server](#server) * [SecureServer](#secureserver) * [ConnectionInterface](#connectioninterface) @@ -42,13 +48,6 @@ $socket->listen(1337); $loop->run(); ``` -You can change the host the socket is listening on through a second parameter -provided to the listen method: - -```php -$socket->listen(1337, '192.168.0.1'); -``` - See also the [examples](examples). Here's a client that outputs the output of said server and then attempts to @@ -69,9 +68,105 @@ $loop->run(); ## Usage +### ServerInterface + +The `ServerInterface` is responsible for providing an interface for accepting +incoming streaming connections, such as a normal TCP/IP connection. + +Most higher-level components (such as a HTTP server) accept an instance +implementing this interface to accept incoming streaming connections. +This is usually done via dependency injection, so it's fairly simple to actually +swap this implementation against any other implementation of this interface. +This means that you SHOULD typehint against this interface instead of a concrete +implementation of this interface. + +Besides defining a few methods, this interface also implements the +[`EventEmitterInterface`](https://github.com/igorw/evenement) +which allows you to react to certain events. + +#### connection event + +The `connection` event will be emitted whenever a new connection has been +established, i.e. a new client connects to this server socket: + +```php +$server->on('connection', function (ConnectionInterface $connection) { + echo 'new connection' . PHP_EOL; +}); +``` + +See also the [`ConnectionInterface`](#connectioninterface) for more details +about handling the incoming connection. + +#### error event + +The `error` event will be emitted whenever there's an error accepting a new +connection from a client. + +```php +$server->on('error', function (Exception $e) { + echo 'error: ' . $e->getMessage() . PHP_EOL; +}); +``` + +Note that this is not a fatal error event, i.e. the server keeps listening for +new connections even after this event. + +#### listen() + +The `listen(int $port, string $host = '127.0.0.1'): void` method can be used to +start listening on the given address. + +This starts accepting new incoming connections on the given address. +See also the [connection event](#connection-event) for more details. + +```php +$server->listen(8080); +``` + +By default, the server will listen on the localhost address and will not be +reachable from the outside. +You can change the host the socket is listening on through a second parameter +provided to the listen method: + +```php +$socket->listen(1337, '192.168.0.1'); +``` + +This method MUST NOT be called more than once on the same instance. + +#### getPort() + +The `getPort(): int` method can be used to +return the port this server is currently listening on. + +```php +$port = $server->getPort(); +echo 'Server listening on port ' . $port . PHP_EOL; +``` + +This method MUST NOT be called before calling [`listen()`](#listen). +This method MUST NOT be called after calling [`shutdown()`](#shutdown). + +#### shutdown() + +The `shutdown(): void` method can be used to +shut down this listening socket. + +This will stop listening for new incoming connections on this socket. + +```php +echo 'Shutting down server socket' . PHP_EOL; +$server->shutdown(); +``` + +This method MUST NOT be called before calling [`listen()`](#listen). +This method MUST NOT be called after calling [`shutdown()`](#shutdown). + ### Server -The `Server` class is responsible for listening on a port and waiting for new connections. +The `Server` class implements the [`ServerInterface`](#serverinterface) and +is responsible for accepting plaintext TCP/IP connections. Whenever a client connects, it will emit a `connection` event with a connection instance implementing [`ConnectionInterface`](#connectioninterface): @@ -85,10 +180,16 @@ $server->on('connection', function (ConnectionInterface $connection) { }); ``` +See also the [`ServerInterface`](#serverinterface) for more details. + +Note that the `Server` class is a concrete implementation for TCP/IP sockets. +If you want to typehint in your higher-level protocol implementation, you SHOULD +use the generic [`ServerInterface`](#serverinterface) instead. + ### SecureServer -The `SecureServer` class implements the `ServerInterface` and is responsible -for providing a secure TLS (formerly known as SSL) server. +The `SecureServer` class implements the [`ServerInterface`](#serverinterface) +and is responsible for providing a secure TLS (formerly known as SSL) server. It does so by wrapping a [`Server`](#server) instance which waits for plaintext TCP/IP connections and then performs a TLS handshake for each connection. @@ -142,6 +243,8 @@ $server->on('error', function (Exception $e) { }); ``` +See also the [`ServerInterface`](#serverinterface) for more details. + ### ConnectionInterface The `ConnectionInterface` is used to represent any incoming connection. diff --git a/src/Server.php b/src/Server.php index dbc4055d..a8674f02 100644 --- a/src/Server.php +++ b/src/Server.php @@ -5,7 +5,30 @@ use Evenement\EventEmitter; use React\EventLoop\LoopInterface; -/** Emits the connection event */ +/** + * The `Server` class implements the `ServerInterface` and + * is responsible for accepting plaintext TCP/IP connections. + * + * Whenever a client connects, it will emit a `connection` event with a connection + * instance implementing `ConnectionInterface`: + * + * ```php + * $server->on('connection', function (ConnectionInterface $connection) { + * echo 'Plaintext connection from ' . $connection->getRemoteAddress() . PHP_EOL; + * $connection->write('hello there!' . PHP_EOL); + * … + * }); + * ``` + * + * See also the `ServerInterface` for more details. + * + * Note that the `Server` class is a concrete implementation for TCP/IP sockets. + * If you want to typehint in your higher-level protocol implementation, you SHOULD + * use the generic `ServerInterface` instead. + * + * @see ServerInterface + * @see ConnectionInterface + */ class Server extends EventEmitter implements ServerInterface { public $master; diff --git a/src/ServerInterface.php b/src/ServerInterface.php index 85ab0ed5..b90448f0 100644 --- a/src/ServerInterface.php +++ b/src/ServerInterface.php @@ -4,10 +4,89 @@ use Evenement\EventEmitterInterface; -/** Emits the connection event */ +/** + * The `ServerInterface` is responsible for providing an interface for accepting + * incoming streaming connections, such as a normal TCP/IP connection. + * + * Most higher-level components (such as a HTTP server) accept an instance + * implementing this interface to accept incoming streaming connections. + * This is usually done via dependency injection, so it's fairly simple to actually + * swap this implementation against any other implementation of this interface. + * This means that you SHOULD typehint against this interface instead of a concrete + * implementation of this interface. + * + * Besides defining a few methods, this interface also implements the + * `EventEmitterInterface` which allows you to react to certain events: + * + * connection event: + * The `connection` event will be emitted whenever a new connection has been + * established, i.e. a new client connects to this server socket: + * + * ```php + * $server->on('connection', function (ConnectionInterface $connection) { + * echo 'new connection' . PHP_EOL; + * }); + * ``` + * + * See also the `ConnectionInterface` for more details about handling the + * incoming connection. + * + * error event: + * The `error` event will be emitted whenever there's an error accepting a new + * connection from a client. + * + * ```php + * $server->on('error', function (Exception $e) { + * echo 'error: ' . $e->getMessage() . PHP_EOL; + * }); + * ``` + * + * Note that this is not a fatal error event, i.e. the server keeps listening for + * new connections even after this event. + * + * @see ConnectionInterface + */ interface ServerInterface extends EventEmitterInterface { + /** + * Starts listening on the given address + * + * This starts accepting new incoming connections on the given address. + * See also the `connection event` above for more details. + * + * By default, the server will listen on the localhost address and will not be + * reachable from the outside. + * You can change the host the socket is listening on through a second parameter + * provided to the listen method. + * + * This method MUST NOT be called more than once on the same instance. + * + * @param int $port port to listen on + * @param string $host optional host to listen on, defaults to localhost IP + * @return void + * @throws Exception if listening on this address fails (invalid or already in use etc.) + */ public function listen($port, $host = '127.0.0.1'); + + /** + * Returns the port this server is currently listening on + * + * This method MUST NOT be called before calling listen(). + * This method MUST NOT be called after calling shutdown(). + * + * @return int the port number + */ public function getPort(); + + /** + * Shuts down this listening socket + * + * This will stop listening for new incoming connections on this socket. + * + * This method MUST NOT be called before calling listen(). + * This method MUST NOT be called after calling shutdown(). + * + * @return void + */ public function shutdown(); }