From e9e61b1d08fe649b3801cf35cdcb1fc4c907a9d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Jensen?= Date: Sat, 30 May 2020 13:10:03 +0200 Subject: [PATCH 1/2] Documentation --- README.md | 224 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 191 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 1cd8058..d6c4408 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,14 @@ -Websocket Client for PHP -======================== +# Websocket Client for PHP -[![Build Status](https://travis-ci.org/Textalk/websocket-php.png)](https://travis-ci.org/Textalk/websocket-php) -[![Coverage Status](https://coveralls.io/repos/Textalk/websocket-php/badge.png)](https://coveralls.io/r/Textalk/websocket-php) +[![Build Status](https://travis-ci.org/Textalk/websocket-php.svg?branch=master)](https://travis-ci.org/Textalk/websocket-php) +[![Coverage Status](https://coveralls.io/repos/github/Textalk/websocket-php/badge.svg?branch=master)](https://coveralls.io/github/Textalk/websocket-php) -This package mainly contains a WebSocket client for PHP. +This library contains WebSocket client and server for PHP. -I made it because the state of other WebSocket clients I could found was either very poor -(sometimes failing on large frames) or had huge dependencies (React…). +The client and server provides methods for reading and writing to WebSocket streams. +It does not include convenience operations such as listeners and implicit error handling. -The Client should be good. - -The Server there because much of the code would be identical in writing a server, and because it is -used for the tests. To be really useful though, there should be a Connection-class returned from a -new Connection, and the Server-class only handling the handshake. Then you could hold a full array -of Connections and check them periodically for new data, send something to them all or fork off a -process handling one connection. But, I have no use for that right now. (Actually, I would -suggest a language with better asynchronous handling than PHP for that.) - -Installing ----------- +## Installing Preferred way to install is with [Composer](https://getcomposer.org/). ``` @@ -28,22 +17,182 @@ composer require textalk/websocket Currently support PHP versions `^5.4` and `^7.0`. +## Client + +The client can read and write on a WebSocket stream. +It internally supports Upgrade handshake, as well us close and ping/pong operations. + +### Class synopsis -Client usage: -------------- ```php -require('vendor/autoload.php'); +WebSocket\Client { + + public __construct(string $uri, array $options = []) + public __destruct() + + public send(mixed $payload, string $opcode = 'text', bool $masked = true) : void + public receive() : mixed + public close(int $status = 1000, mixed $message = 'ttfn') : mixed + + public getLastOpcode() : string + public getCloseStatus() : int + public isConnected() : bool + public setTimeout(int $seconds) : void + public setFragmentSize(int $fragment_size) : self + public getFragmentSize() : int +} +``` + +### Example: Simple send-receive operation + +This example send a single message to a server, and output the response. +```php use WebSocket\Client; $client = new Client("ws://echo.websocket.org/"); $client->send("Hello WebSocket.org!"); - echo $client->receive(); // Will output 'Hello WebSocket.org!' +$client->close(); +``` + +### Example: Listening to a server + +To continuously listen to incoming messages, you need to put the receive operation within a loop. +Note that these functions **always** throw exception on any failure, including recoverable failures such as connection time out. +By consuming exceptions, the code will re-connect the socket in next loop iteration. + +```php +use WebSocket\Client; + +$client = new Client("ws://echo.websocket.org/"); +while (true) { + try { + $message = $client->receive(); + // Act on received message + // Break while loop to stop listening + } catch (\WebSocket\ConnectionException $e) { + // Possibly log errors + } +} +$client->close(); +``` + +### Constructor options + +The `$options` parameter in constructor accepts an associative array of options. + +* `timeout` - Time out in seconds. Default 5 seconds. +* `fragment_size` - Maximum payload size. Default 4096 chars. +* `context` - A stream context created using [stream_context_create](https://www.php.net/manual/en/function.stream-context-create). +* `headers` - Additional headers as associative array name => content. + +```php +use WebSocket\Client; + +$context = stream_context_create(); +stream_context_set_option($context, 'ssl', 'verify_peer', false); +stream_context_set_option($context, 'ssl', 'verify_peer_name', false); + +$client = new Client("ws://echo.websocket.org/", [ + 'timeout' => 60, // 1 minute time out + 'context' => $context, + 'headers' => [ + 'Sec-WebSocket-Protocol' => 'soap', + 'origin' => 'localhost', + ], +]); +``` + +## Server + +The library contains a rudimentary single stream/single threaded server. +It internally supports Upgrade handshake, as well us close and ping/pong operations. + +Note that it does **not** support threading or automatic association ot continuous client requests. +If you require this kind of server behavior, you need to build it on top of provided server implementation. + +### Class synopsis + +```php +WebSocket\Server { + + public __construct(array $options = []) + public __destruct() + + public accept() : bool + public send(mixed $payload, string $opcode = 'text', bool $masked = true) : void + public receive() : mixed + public close(int $status = 1000, mixed $message = 'ttfn') : mixed + + public getPort() : int + public getPath() : string + public getRequest() : array + public getHeader(string $header_name) : string|null + + public getLastOpcode() : string + public getCloseStatus() : int + public isConnected() : bool + public setTimeout(int $seconds) : void + public setFragmentSize(int $fragment_size) : self + public getFragmentSize() : int +} +``` + +### Example: Simple receive-send operation + +This example reads a single message from a client, and respond with the same message. + +```php +use WebSocket\Server; + +$server = new Server(); +$server->accept(); +$message = $server->receive(); +$server->send($message); +$server->close(); ``` -Development and contribution ------------------ +### Example: Listening to clients + +To continuously listen to incoming messages, you need to put the receive operation within a loop. +Note that these functions **always** throw exception on any failure, including recoverable failures such as connection time out. +By consuming exceptions, the code will re-connect the socket in next loop iteration. + +```php +use WebSocket\Server; + +$server = new Server(); +while ($server->accept()) { + try { + $message = $server->receive(); + // Act on received message + // Break while loop to stop listening + } catch (\WebSocket\ConnectionException $e) { + // Possibly log errors + } +} +$server->close(); +``` + +### Constructor options + +The `$options` parameter in constructor accepts an associative array of options. + +* `timeout` - Time out in seconds. Default 5 seconds. +* `port` - The server port to listen to. Default 8000. +* `fragment_size` - Maximum payload size. Default 4096 chars. + +```php +use WebSocket\Server; + +$server = new Server([ + 'timeout' => 60, // 1 minute time out + 'port' => 9000, +]); +``` + +## Development and contribution Install or update dependencies using [Composer](https://getcomposer.org/). ``` @@ -66,13 +215,9 @@ Unit tests with [PHPUnit](https://phpunit.readthedocs.io/). make test ``` -License ([ISC](http://en.wikipedia.org/wiki/ISC_license)) ---------------------------------------------------------- +## License ([ISC](http://en.wikipedia.org/wiki/ISC_license)) -Copyright (C) 2014-2020 Textalk/Abicart -Copyright (C) 2015 Patrick McCarren - added payload fragmentation for huge payloads -Copyright (C) 2015 Ignas Bernotas - added stream context options -Copyright (C) 2015 Patrick McCarren - added ping/pong support +Copyright (C) 2014-2020 Textalk/Abicart and contributors. Websocket PHP is free software: Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and @@ -85,11 +230,24 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -See COPYING. +See ([Copying](COPYING)). + +### Contributors + +Fredrik Liljegren, Armen Baghumian Sankbarani, Ruslan Bekenev, +Joshua Thijssen, Simon Lipp, Quentin Bellus, Patrick McCarren, swmcdonnell, +Ignas Bernotas, Mark Herhold, Andreas Palm, Sören Jensen, pmaasz, Alexey Stavrov. + + +## Changelog +1.3.0 -Changelog ---------- + * Implements ping/pong frames (@pmccarren) + * Correct ping-pong behaviour (@Logioniz) + * Correct close behaviour + * Various fixes concerning connection handling + * Overhaul of Composer, Travis and Coveralls setup, PSR code standard and unit tests 1.2.0 From a722a7d6a1e226c64806453cf8856748d57aa5d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Jensen?= Date: Sat, 30 May 2020 13:33:37 +0200 Subject: [PATCH 2/2] Documentation --- README.md | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index d6c4408..a3112b0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Websocket Client for PHP +# Websocket Client and Server for PHP [![Build Status](https://travis-ci.org/Textalk/websocket-php.svg?branch=master)](https://travis-ci.org/Textalk/websocket-php) [![Coverage Status](https://coveralls.io/repos/github/Textalk/websocket-php/badge.svg?branch=master)](https://coveralls.io/github/Textalk/websocket-php) @@ -20,7 +20,7 @@ Currently support PHP versions `^5.4` and `^7.0`. ## Client The client can read and write on a WebSocket stream. -It internally supports Upgrade handshake, as well us close and ping/pong operations. +It internally supports Upgrade handshake and implicit close and ping/pong operations. ### Class synopsis @@ -48,11 +48,9 @@ WebSocket\Client { This example send a single message to a server, and output the response. ```php -use WebSocket\Client; - -$client = new Client("ws://echo.websocket.org/"); +$client = new WebSocket\Client("ws://echo.websocket.org/"); $client->send("Hello WebSocket.org!"); -echo $client->receive(); // Will output 'Hello WebSocket.org!' +echo $client->receive(); $client->close(); ``` @@ -63,9 +61,7 @@ Note that these functions **always** throw exception on any failure, including r By consuming exceptions, the code will re-connect the socket in next loop iteration. ```php -use WebSocket\Client; - -$client = new Client("ws://echo.websocket.org/"); +$client = new WebSocket\Client("ws://echo.websocket.org/"); while (true) { try { $message = $client->receive(); @@ -88,13 +84,11 @@ The `$options` parameter in constructor accepts an associative array of options. * `headers` - Additional headers as associative array name => content. ```php -use WebSocket\Client; - $context = stream_context_create(); stream_context_set_option($context, 'ssl', 'verify_peer', false); stream_context_set_option($context, 'ssl', 'verify_peer_name', false); -$client = new Client("ws://echo.websocket.org/", [ +$client = new WebSocket\Client("ws://echo.websocket.org/", [ 'timeout' => 60, // 1 minute time out 'context' => $context, 'headers' => [ @@ -106,8 +100,8 @@ $client = new Client("ws://echo.websocket.org/", [ ## Server -The library contains a rudimentary single stream/single threaded server. -It internally supports Upgrade handshake, as well us close and ping/pong operations. +The library contains a rudimentary single stream/single thread server. +It internally supports Upgrade handshake and implicit close and ping/pong operations. Note that it does **not** support threading or automatic association ot continuous client requests. If you require this kind of server behavior, you need to build it on top of provided server implementation. @@ -144,9 +138,7 @@ WebSocket\Server { This example reads a single message from a client, and respond with the same message. ```php -use WebSocket\Server; - -$server = new Server(); +$server = new WebSocket\Server(); $server->accept(); $message = $server->receive(); $server->send($message); @@ -160,9 +152,7 @@ Note that these functions **always** throw exception on any failure, including r By consuming exceptions, the code will re-connect the socket in next loop iteration. ```php -use WebSocket\Server; - -$server = new Server(); +$server = new WebSocket\Server(); while ($server->accept()) { try { $message = $server->receive(); @@ -184,14 +174,19 @@ The `$options` parameter in constructor accepts an associative array of options. * `fragment_size` - Maximum payload size. Default 4096 chars. ```php -use WebSocket\Server; - -$server = new Server([ +$server = new WebSocket\Server([ 'timeout' => 60, // 1 minute time out 'port' => 9000, ]); ``` +## Exceptions + +* `WebSocket\BadOpcodeException` - Thrown if provided opcode is invalid. +* `WebSocket\BadUriException` - Thrown if provided URI is invalid. +* `WebSocket\ConnectionException` - Thrown on any socket I/O failure. + + ## Development and contribution Install or update dependencies using [Composer](https://getcomposer.org/). @@ -230,7 +225,7 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -See ([Copying](COPYING)). +See [Copying](COPYING). ### Contributors @@ -245,9 +240,9 @@ Ignas Bernotas, Mark Herhold, Andreas Palm, Sören Jensen, pmaasz, Alexey Stavro * Implements ping/pong frames (@pmccarren) * Correct ping-pong behaviour (@Logioniz) - * Correct close behaviour - * Various fixes concerning connection handling - * Overhaul of Composer, Travis and Coveralls setup, PSR code standard and unit tests + * Correct close behaviour (@sirn-se) + * Various fixes concerning connection handling (@sirn-se) + * Overhaul of Composer, Travis and Coveralls setup, PSR code standard and unit tests (@sirn-se) 1.2.0