8000 Improve documentation for PubSub and events by clue · Pull Request #90 · clue/reactphp-redis · GitHub
[go: up one dir, main page]

Skip to content

Improve documentation for PubSub and events #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 121 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ It enables you to set and query its data or use its PubSub topics to react to in
* [Client](#client)
* [Commands](#commands)
* [Promises](#promises)
* [on()](#on)
* [PubSub](#pubsub)
* [close()](#close)
* [end()](#end)
* [error event](#error-event)
* [close event](#close-event)
* [Install](#install)
* [Tests](#tests)
* [License](#license)
Expand Down Expand Up @@ -333,6 +335,9 @@ $factory->createLazyClient('localhost?idle=0.1');
The `Client` is responsible for exchanging messages with Redis
and keeps track of pending commands.

Besides defining a few methods, this interface also implements the
`EventEmitterInterface` which allows you to react to certain events as documented below.

#### Commands

All [Redis commands](http://redis.io/commands) are automatically available as public methods like this:
Expand Down Expand Up @@ -379,27 +384,94 @@ $client->get('hello')->then(function ($response) {
});
```

#### on()
#### PubSub

This library is commonly used to efficiently transport messages using Redis'
[Pub/Sub](https://redis.io/topics/pubsub) (Publish/Subscribe) channels. For
instance, this can be used to distribute single messages to a larger number
of subscribers (think horizontal scaling for chat-like applications) or as an
efficient message transport in distributed systems (microservice architecture).

The `on($eventName, $eventHandler)` method can be used to register a new event handler.
Incoming events and errors will be forwarded to registered event handler callbacks:
The [`PUBLISH` command](https://redis.io/commands/publish) can be used to
send a message to all clients currently subscribed to a given channel:

```php
// global events:
$client->on('close', function () {
// the connection to Redis just closed
});
$client->on('error', function (Exception $e) {
// and error has just been detected, the connection will terminate...
});
$channel = 'user';
$message = json_encode(array('id' => 10));
$client->publish($channel, $message);
```

The [`SUBSCRIBE` command](https://redis.io/commands/subscribe) can be used to
subscribe to a channel and then receive incoming PubSub `message` events:

```php
$channel = 'user';
$client->subscribe($channel);

// pubsub events:
$client->on('message', function ($channel, $payload) {
// pubsub message received on given $channel
var_dump($channel, json_decode($payload));
});
```

Likewise, you can use the same client connection to subscribe to multiple
channels by simply executing this command multiple times:

```php
$client->subscribe('user.register');
$client->subscribe('user.join');
$client->subscribe('user.leave');
```

Similarly, the [`PSUBSCRIBE` command](https://redis.io/commands/psubscribe) can
be used to subscribe to all channels matching a given pattern and then receive
all incoming PubSub messages with the `pmessage` event:


```php
$pattern = 'user.*';
$client->psubscribe($pattern);

$client->on('pmessage', function ($pattern, $channel, $payload) {
// pubsub message received matching given $pattern
var_dump($channel, json_decode($payload));
});
```

Once you're in a subscribed state, Redis no longer allows executing any other
commands on the same client connection. This is commonly worked around by simply
creating a second client connection and dedicating one client connection solely
for PubSub subscriptions and the other for all other commands.

The [`UNSUBSCRIBE` command](https://redis.io/commands/unsubscribe) and
[`PUNSUBSCRIBE` command](https://redis.io/commands/punsubscribe) can be used to
unsubscribe from active subscriptions if you're no longer interested in
receiving any further events for the given channel and pattern subscriptions
respectively:

```php
$client->subscribe('user');

$loop->addTimer(60.0, function () use ($client) {
$client->unsubscribe('user');
});
```

Likewise, once you've unsubscribed the last channel and pattern, the client
connection is no longer in a subscribed state and you can issue any other
command over this client connection again.

Each of the above methods follows normal request-response semantics and return
a [`Promise`](#promises) to await successful subscriptions. Note that while
Redis allows a variable number of arguments for each of these commands, this
library is currently limited to single arguments for each of these methods in
order to match exactly one response to each command request. As an alternative,
the methods can simply be invoked multiple times with one argument each.

Additionally, can listen for the following PubSub events to get notifications
about subscribed/unsubscribed channels and patterns:

```php
$client->on('subscribe', function ($channel, $total) {
// subscribed to given $channel
});
Expand All @@ -414,13 +486,48 @@ $client->on('punsubscribe', function ($pattern, $total) {
});
```

When using the [`createLazyClient()`](#createlazyclient) method, the `unsubscribe`
and `punsubscribe` events will be invoked automatically when the underlying
connection is lost. This gives you control over re-subscribing to the channels
and patterns as appropriate.

#### close()

The `close()` method can be used to force-close the Redis connection and reject all pending commands.
The `close():void` method can be used to
force-close the Redis connection and reject all pending commands.

#### end()

The `end()` method can be used to soft-close the Redis connection once all pending commands are completed.
The `end():void` method can be used to
soft-close the Redis connection once all pending commands are completed.

#### error event

The `error` event will be emitted once a fatal error occurs, such as
when the client connection is lost or is invalid.
The event receives a single `Exception` argument for the error instance.

```php
$client->on('error', function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});
```

This event will only be triggered for fatal errors and will be followed
by closing the client connection. It is not to be confused with "soft"
errors caused by invalid commands.

#### close event

The `close` event will be emitted once the client connection closes (terminates).

```php
$client->on('close', function () {
echo 'Connection closed' . PHP_EOL;
});
```

See also the [`close()`](#close) method.

## Install

Expand Down
4 changes: 3 additions & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ interface Client extends EventEmitterInterface
*
* @param string $name
* @param string[] $args
* @return PromiseInterface Promise<mixed, Exception>
* @return PromiseInterface Promise<mixed,Exception>
*/
public function __call($name, $args);

/**
* end connection once all pending requests have been replied to
*
* @return void
* @uses self::close() once all replies have been received
* @see self::close() for closing the connection immediately
*/
Expand All @@ -46,6 +47,7 @@ public function end();
*
* This will emit the "close" event.
*
* @return void
* @see self::end() for closing the connection once the client is idle
*/
public function close();
Expand Down
0