@@ -31,9 +31,11 @@ It enables you to set and query its data or use its PubSub topics to react to in
3131 * [ Client] ( #client )
3232 * [ Commands] ( #commands )
3333 * [ Promises] ( #promises )
34- * [ on() ] ( #on )
34+ * [ PubSub ] ( #pubsub )
3535 * [ close()] ( #close )
3636 * [ end()] ( #end )
37+ * [ error event] ( #error-event )
38+ * [ close event] ( #close-event )
3739* [ Install] ( #install )
3840* [ Tests] ( #tests )
3941* [ License] ( #license )
@@ -333,6 +335,9 @@ $factory->createLazyClient('localhost?idle=0.1');
333335The ` Client ` is responsible for exchanging messages with Redis
334336and keeps track of pending commands.
335337
338+ Besides defining a few methods, this interface also implements the
339+ ` EventEmitterInterface ` which allows you to react to certain events as documented below.
340+
336341#### Commands
337342
338343All [ Redis commands] ( http://redis.io/commands ) are automatically available as public methods like this:
@@ -379,27 +384,94 @@ $client->get('hello')->then(function ($response) {
379384});
380385```
381386
382- #### on()
387+ #### PubSub
388+
389+ This library is commonly used to efficiently transport messages using Redis'
390+ [ Pub/Sub] ( https://redis.io/topics/pubsub ) (Publish/Subscribe) channels. For
391+ instance, this can be used to distribute single messages to a larger number
392+ of subscribers (think horizontal scaling for chat-like applications) or as an
393+ efficient message transport in distributed systems (microservice architecture).
383394
384- The ` on($eventName, $eventHandler) ` method can be used to register a new event handler.
385- Incoming events and errors will be forwarded to registered event handler callbacks :
395+ The [ ` PUBLISH ` command ] ( https://redis.io/commands/publish ) can be used to
396+ send a message to all clients currently subscribed to a given channel :
386397
387398``` php
388- // global events:
389- $client->on('close', function () {
390- // the connection to Redis just closed
391- });
392- $client->on('error', function (Exception $e) {
393- // and error has just been detected, the connection will terminate...
394- });
399+ $channel = 'user';
400+ $message = json_encode(array('id' => 10));
401+ $client->publish($channel, $message);
402+ ```
403+
404+ The [ ` SUBSCRIBE ` command] ( https://redis.io/commands/subscribe ) can be used to
405+ subscribe to a channel and then receive incoming PubSub ` message ` events:
406+
407+ ``` php
408+ $channel = 'user';
409+ $client->subscribe($channel);
395410
396- // pubsub events:
397411$client->on('message', function ($channel, $payload) {
398412 // pubsub message received on given $channel
413+ var_dump($channel, json_decode($payload));
399414});
415+ ```
416+
417+ Likewise, you can use the same client connection to subscribe to multiple
418+ channels by simply executing this command multiple times:
419+
420+ ``` php
421+ $client->subscribe('user.register');
422+ $client->subscribe('user.join');
423+ $client->subscribe('user.leave');
424+ ```
425+
426+ Similarly, the [ ` PSUBSCRIBE ` command] ( https://redis.io/commands/psubscribe ) can
427+ be used to subscribe to all channels matching a given pattern and then receive
428+ all incoming PubSub messages with the ` pmessage ` event:
429+
430+
431+ ``` php
432+ $pattern = 'user.*';
433+ $client->psubscribe($pattern);
434+
400435$client->on('pmessage', function ($pattern, $channel, $payload) {
401436 // pubsub message received matching given $pattern
437+ var_dump($channel, json_decode($payload));
402438});
439+ ```
440+
441+ Once you're in a subscribed state, Redis no longer allows executing any other
442+ commands on the same client connection. This is commonly worked around by simply
443+ creating a second client connection and dedicating one client connection solely
444+ for PubSub subscriptions and the other for all other commands.
445+
446+ The [ ` UNSUBSCRIBE ` command] ( https://redis.io/commands/unsubscribe ) and
447+ [ ` PUNSUBSCRIBE ` command] ( https://redis.io/commands/punsubscribe ) can be used to
448+ unsubscribe from active subscriptions if you're no longer interested in
449+ receiving any further events for the given channel and pattern subscriptions
450+ respectively:
451+
452+ ``` php
453+ $client->subscribe('user');
454+
455+ $loop->addTimer(60.0, function () use ($client) {
456+ $client->unsubscribe('user');
457+ });
458+ ```
459+
460+ Likewise, once you've unsubscribed the last channel and pattern, the client
461+ connection is no longer in a subscribed state and you can issue any other
462+ command over this client connection again.
463+
464+ Each of the above methods follows normal request-response semantics and return
465+ a [ ` Promise ` ] ( #promises ) to await successful subscriptions. Note that while
466+ Redis allows a variable number of arguments for each of these commands, this
467+ library is currently limited to single arguments for each of these methods in
468+ order to match exactly one response to each command request. As an alternative,
469+ the methods can simply be invoked multiple times with one argument each.
470+
471+ Additionally, can listen for the following PubSub events to get notifications
472+ about subscribed/unsubscribed channels and patterns:
473+
474+ ``` php
403475$client->on('subscribe', function ($channel, $total) {
404476 // subscribed to given $channel
405477});
@@ -414,13 +486,48 @@ $client->on('punsubscribe', function ($pattern, $total) {
414486});
415487```
416488
489+ When using the [ ` createLazyClient() ` ] ( #createlazyclient ) method, the ` unsubscribe `
490+ and ` punsubscribe ` events will be invoked automatically when the underlying
491+ connection is lost. This gives you control over re-subscribing to the channels
492+ and patterns as appropriate.
493+
417494#### close()
418495
419- The ` close() ` method can be used to force-close the Redis connection and reject all pending commands.
496+ The ` close():void ` method can be used to
497+ force-close the Redis connection and reject all pending commands.
420498
421499#### end()
422500
423- The ` end() ` method can be used to soft-close the Redis connection once all pending commands are completed.
501+ The ` end():void ` method can be used to
502+ soft-close the Redis connection once all pending commands are completed.
503+
504+ #### error event
505+
506+ The ` error ` event will be emitted once a fatal error occurs, such as
507+ when the client connection is lost or is invalid.
508+ The event receives a single ` Exception ` argument for the error instance.
509+
510+ ``` php
511+ $client->on('error', function (Exception $e) {
512+ echo 'Error: ' . $e->getMessage() . PHP_EOL;
513+ });
514+ ```
515+
516+ This event will only be triggered for fatal errors and will be followed
517+ by closing the client connection. It is not to be confused with "soft"
518+ errors caused by invalid commands.
519+
520+ #### close event
521+
522+ The ` close ` event will be emitted once the client connection closes (terminates).
523+
524+ ``` php
525+ $client->on('close', function () {
526+ echo 'Connection closed' . PHP_EOL;
527+ });
528+ ```
529+
530+ See also the [ ` close() ` ] ( #close ) method.
424531
425532## Install
426533
0 commit comments