From 81ef836c1db9daa025ae59d2ad2c5fc0bf30e5b7 Mon Sep 17 00:00:00 2001 From: Aaron Stephens Date: Fri, 22 Mar 2013 01:42:46 +0000 Subject: [PATCH 1/5] Added support for varying client connection schemes and buffered IO connection. --- src/DNode/Connection.php | 33 +++++++++++++++++++++++++++++++++ src/DNode/DNode.php | 17 ++++++++++++----- src/DNode/Protocol.php | 4 ++++ 3 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/DNode/Connection.php diff --git a/src/DNode/Connection.php b/src/DNode/Connection.php new file mode 100644 index 0000000..854c3ed --- /dev/null +++ b/src/DNode/Connection.php @@ -0,0 +1,33 @@ +streamReadFunctionName = 'stream_socket_recvfrom'; + } + } + + public function handleData($stream) + { + $data = call_user_func_array($this->streamReadFunctionName, array($stream, $this->bufferSize)); + + if ('' === $data || false === $data) { + $this->end(); + } else { + $this->emit('data', array($data, $this)); + } + } +} \ No newline at end of file diff --git a/src/DNode/DNode.php b/src/DNode/DNode.php index bd76131..069ee70 100644 --- a/src/DNode/DNode.php +++ b/src/DNode/DNode.php @@ -3,7 +3,6 @@ use Evenement\EventEmitter; use React\EventLoop\LoopInterface; use React\Socket\Server; -use React\Socket\Connection; use React\Socket\ConnectionInterface; class DNode extends EventEmitter @@ -30,17 +29,25 @@ public function using($middleware) public function connect() { $params = $this->protocol->parseArgs(func_get_args()); + + if (!isset($params['scheme'])) { + $params['scheme'] = 'tcp:'; + } + if (!isset($params['host'])) { $params['host'] = '127.0.0.1'; } if (!isset($params['port'])) { - throw new \Exception("For now we only support TCP connections to a defined port"); + throw new \Exception("For now we only support connections to a defined port"); } - $client = @stream_socket_client("tcp://{$params['host']}:{$params['port']}"); + $url = "{$params['scheme']}//{$params['host']}:{$params['port']}"; + $client = @stream_socket_client($url); + if (!$client) { - $e = new \RuntimeException("No connection to DNode server in tcp://{$params['host']}:{$params['port']}"); + $e = new \RuntimeException("No connection to DNode server in $url"); + $this->emit('error', array($e)); if (!count($this->listeners('error'))) { @@ -50,7 +57,7 @@ public function connect() return; } - $conn = new Connection($client, $this->loop); + $conn = new Connection($client, $this->loop, $params['scheme']); $this->handleConnection($conn, $params); } diff --git a/src/DNode/Protocol.php b/src/DNode/Protocol.php index c7b1865..74e2b80 100644 --- a/src/DNode/Protocol.php +++ b/src/DNode/Protocol.php @@ -53,6 +53,10 @@ public function parseArgs($args) { $params['path'] = $arg; continue; } + if (preg_match('/\w+:$/', $arg)) { + $params['scheme'] = $arg; + continue; + } $params['host'] = $arg; continue; } From 38057aa35cca8e99dbc6ea688deba8bb3506d59e Mon Sep 17 00:00:00 2001 From: Aaron Stephens Date: Wed, 15 May 2013 00:59:20 +0100 Subject: [PATCH 2/5] Updated scheme handling to no longer include trailing color or pass scheme to client connections --- src/DNode/DNode.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DNode/DNode.php b/src/DNode/DNode.php index 069ee70..b0f75a0 100644 --- a/src/DNode/DNode.php +++ b/src/DNode/DNode.php @@ -31,7 +31,7 @@ public function connect() $params = $this->protocol->parseArgs(func_get_args()); if (!isset($params['scheme'])) { - $params['scheme'] = 'tcp:'; + $params['scheme'] = 'tcp'; } if (!isset($params['host'])) { @@ -42,7 +42,7 @@ public function connect() throw new \Exception("For now we only support connections to a defined port"); } - $url = "{$params['scheme']}//{$params['host']}:{$params['port']}"; + $url = "{$params['scheme']}://{$params['host']}:{$params['port']}"; $client = @stream_socket_client($url); if (!$client) { @@ -57,7 +57,7 @@ public function connect() return; } - $conn = new Connection($client, $this->loop, $params['scheme']); + $conn = new Connection($client, $this->loop); $this->handleConnection($conn, $params); } From 60bcff3467a40944fa2298fd60991442710833d4 Mon Sep 17 00:00:00 2001 From: Aaron Stephens Date: Wed, 15 May 2013 01:00:59 +0100 Subject: [PATCH 3/5] Updated connection to always use fread --- src/DNode/Connection.php | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/DNode/Connection.php b/src/DNode/Connection.php index 854c3ed..a34bb9a 100644 --- a/src/DNode/Connection.php +++ b/src/DNode/Connection.php @@ -5,24 +5,15 @@ class Connection extends BaseConnection { - private $streamReadFunctionName = 'fread'; + private $lastBufferSize; - private static $rawIoSchemes = array( - 'tcp', - 'udp' - ); - - public function __construct($stream, LoopInterface $loop, $scheme) + public function handleData($stream) { - parent::__construct($stream, $loop); - if (in_array($scheme, static::$rawIoSchemes)) { - $this->streamReadFunctionName = 'stream_socket_recvfrom'; + if ($this->bufferSize != $this->lastBufferSize) { + $this->adjustReadBufferSize($stream); } - } - public function handleData($stream) - { - $data = call_user_func_array($this->streamReadFunctionName, array($stream, $this->bufferSize)); + $data = fread($stream, $this->bufferSize); if ('' === $data || false === $data) { $this->end(); @@ -30,4 +21,12 @@ public function handleData($stream) $this->emit('data', array($data, $this)); } } + + protected function adjustReadBufferSize($stream) + { + $this->lastBufferSize = $this->bufferSize; + if (0 !== stream_set_read_buffer($stream, 0)) { + throw new \RuntimeException('Unable to set read buffer on stream'); + } + } } \ No newline at end of file From f63743778244ce94d1bef05990b1e58d5841b95d Mon Sep 17 00:00:00 2001 From: Aaron Stephens Date: Wed, 15 May 2013 01:02:57 +0100 Subject: [PATCH 4/5] Removed scheme from argument parsing (now must be passed in array if needed) Modified argument parsing to allow passing array of parameters Updated protocol tests for array argument and invalid argument type --- src/DNode/Protocol.php | 12 +++++------- tests/DNode/ProtocolTest.php | 13 +++++++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/DNode/Protocol.php b/src/DNode/Protocol.php index 74e2b80..e625002 100644 --- a/src/DNode/Protocol.php +++ b/src/DNode/Protocol.php @@ -53,10 +53,6 @@ public function parseArgs($args) { $params['path'] = $arg; continue; } - if (preg_match('/\w+:$/', $arg)) { - $params['scheme'] = $arg; - continue; - } $params['host'] = $arg; continue; } @@ -77,9 +73,11 @@ public function parseArgs($args) { continue; } - foreach ($arg as $key => $value) { - $params[$key] = $value; - } + $arg = (array) $arg; + } + + if (is_array($arg)) { + $params = array_merge($params, $arg); continue; } diff --git a/tests/DNode/ProtocolTest.php b/tests/DNode/ProtocolTest.php index 27c6bfc..30ea643 100644 --- a/tests/DNode/ProtocolTest.php +++ b/tests/DNode/ProtocolTest.php @@ -66,6 +66,11 @@ public function provideParseArgs() $obj->foo = 'bar'; $obj->baz = 'qux'; + $arr = array( + 'quux' => 'corge', + 'grault' => 'garply' + ); + return array( 'string number becomes port' => array( array('port' => '8080'), @@ -83,6 +88,10 @@ public function provideParseArgs() array('port' => 8080), array(8080), ), + 'array becomes merged' => array( + array('quux' => 'corge', 'grault' => 'garply'), + array($arr), + ), 'Closure becomes block' => array( array('block' => $closure), array($closure), @@ -102,11 +111,11 @@ public function provideParseArgs() * @test * @covers DNode\Protocol::parseArgs * @expectedException InvalidArgumentException - * @expectedExceptionMessage Not sure what to do about array arguments + * @expectedExceptionMessage Not sure what to do about boolean arguments */ public function parseArgsShouldRejectInvalidArgs() { - $args = array(array('wat')); + $args = array(true); $this->protocol->parseArgs($args); } } From d361146e895e51efdb35cfbc42f1c77782988c2d Mon Sep 17 00:00:00 2001 From: Aaron Stephens Date: Thu, 16 May 2013 08:34:20 +0100 Subject: [PATCH 5/5] Added check for valid scheme --- src/DNode/DNode.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/DNode/DNode.php b/src/DNode/DNode.php index b0f75a0..c6c3a93 100644 --- a/src/DNode/DNode.php +++ b/src/DNode/DNode.php @@ -42,6 +42,12 @@ public function connect() throw new \Exception("For now we only support connections to a defined port"); } + if (!in_array($params['scheme'], stream_get_transports())) { + $e = new \InvalidArgumentException("Scheme {$params['scheme']} is not supported... are you missing an extension?"); + + $this->emit('error', array($e)); + } + $url = "{$params['scheme']}://{$params['host']}:{$params['port']}"; $client = @stream_socket_client($url);