Skip to content

Commit

Permalink
Merge pull request #81 from Textalk/v1.3-docs
Browse files Browse the repository at this point in the history
V1.3 docs
  • Loading branch information
sirn-se authored May 31, 2020
2 parents 0eaa881 + a722a7d commit 9fbb3b4
Showing 1 changed file with 188 additions and 35 deletions.
223 changes: 188 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
Websocket Client for PHP
========================
# Websocket Client and Server 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/).
```
Expand All @@ -28,22 +17,177 @@ 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 and implicit 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

use WebSocket\Client;
This example send a single message to a server, and output the response.

$client = new Client("ws://echo.websocket.org/");
```php
$client = new WebSocket\Client("ws://echo.websocket.org/");
$client->send("Hello WebSocket.org!");
echo $client->receive();
$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
$client = new WebSocket\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
$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 WebSocket\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 thread server.
It internally supports Upgrade handshake and implicit close and ping/pong operations.

echo $client->receive(); // Will output 'Hello WebSocket.org!'
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
}
```

Development and contribution
-----------------
### Example: Simple receive-send operation

This example reads a single message from a client, and respond with the same message.

```php
$server = new WebSocket\Server();
$server->accept();
$message = $server->receive();
$server->send($message);
$server->close();
```

### 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
$server = new WebSocket\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
$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/).
```
Expand All @@ -66,13 +210,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
Expand All @@ -85,11 +225,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 (@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

Expand Down

0 comments on commit 9fbb3b4

Please sign in to comment.