From 356f22a0624f5179abda73fda2ea7a6b6c2a4d2a Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Wed, 16 Jul 2014 18:49:48 +0200 Subject: [PATCH] Implement PING in PUB/SUB loop abstraction for Redis 3.0.0. --- src/PubSub/AbstractConsumer.php | 12 +++++++++ src/PubSub/Consumer.php | 6 +++++ tests/Predis/PubSub/ConsumerTest.php | 38 +++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/PubSub/AbstractConsumer.php b/src/PubSub/AbstractConsumer.php index c87a151d..98c1b48e 100644 --- a/src/PubSub/AbstractConsumer.php +++ b/src/PubSub/AbstractConsumer.php @@ -26,6 +26,7 @@ abstract class AbstractConsumer implements Iterator const PUNSUBSCRIBE = 'punsubscribe'; const MESSAGE = 'message'; const PMESSAGE = 'pmessage'; + const PONG = 'pong'; const STATUS_VALID = 1; // 0b0001 const STATUS_SUBSCRIBED = 2; // 0b0010 @@ -95,6 +96,17 @@ abstract class AbstractConsumer implements Iterator $this->writeRequest(self::PUNSUBSCRIBE, func_get_args()); } + /** + * PING the server with an optional payload that will be echoed as a + * PONG message in the pub/sub loop. + * + * @param string $payload Optional PING payload. + */ + public function ping($payload = null) + { + $this->writeRequest('PING', array($payload)); + } + /** * Closes the context by unsubscribing from all the subscribed channels. The * context can be forcefully closed by dropping the underlying connection. diff --git a/src/PubSub/Consumer.php b/src/PubSub/Consumer.php index 13fea361..25fb0b42 100644 --- a/src/PubSub/Consumer.php +++ b/src/PubSub/Consumer.php @@ -137,6 +137,12 @@ class Consumer extends AbstractConsumer 'payload' => $response[3], ); + case self::PONG: + return (object) array( + 'kind' => $response[0], + 'payload' => $response[1], + ); + default: throw new ClientException( "Unknown message type '{$response[0]}' received in the PUB/SUB context." diff --git a/tests/Predis/PubSub/ConsumerTest.php b/tests/Predis/PubSub/ConsumerTest.php index 2e27666b..89b7d732 100644 --- a/tests/Predis/PubSub/ConsumerTest.php +++ b/tests/Predis/PubSub/ConsumerTest.php @@ -145,6 +145,42 @@ class ConsumerTest extends PredisTestCase $this->assertNull($pubsub->next()); } + /** + * @group disconnected + */ + public function testHandlesPongMessages() + { + $rawmessage = array('pong', ''); + + $connection = $this->getMock('Predis\Connection\NodeConnectionInterface'); + $connection->expects($this->once())->method('read')->will($this->returnValue($rawmessage)); + + $client = new Client($connection); + $pubsub = new PubSubConsumer($client, array('subscribe' => 'channel:foo')); + + $message = $pubsub->current(); + $this->assertSame('pong', $message->kind); + $this->assertSame('', $message->payload); + } + + /** + * @group disconnected + */ + public function testHandlesPongMessagesWithPayload() + { + $rawmessage = array('pong', 'foobar'); + + $connection = $this->getMock('Predis\Connection\NodeConnectionInterface'); + $connection->expects($this->once())->method('read')->will($this->returnValue($rawmessage)); + + $client = new Client($connection); + $pubsub = new PubSubConsumer($client, array('subscribe' => 'channel:foo')); + + $message = $pubsub->current(); + $this->assertSame('pong', $message->kind); + $this->assertSame('foobar', $message->payload); + } + /** * @group disconnected */ @@ -303,6 +339,6 @@ class ConsumerTest extends PredisTestCase $this->assertSame(array('message1', 'message2', 'QUIT'), $messages); $this->assertFalse($pubsub->valid()); - $this->assertEquals('PONG', $consumer->ping()); + $this->assertEquals('ECHO', $consumer->echo('ECHO')); } }