diff --git a/README.md b/README.md index 7998e62..4b23cac 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A PHP 5.3 (PSR-0) library for serving WebSockets and building socket based applications. Build up your application through simple interfaces and re-use your application without changing any of its code just by combining different components. -##WebSockets +##WebSocket Compliance * Supports the RFC6455, HyBi-10+, and Hixie76 protocol versions (at the same time) * Tested on Chrome 18 - 16, Firefox 6 - 9, Safari 5, iOS 4.2, iOS 5 @@ -73,4 +73,4 @@ class Chat implements MessageComponentInterface { $server->run(); ``` - # php chat.php \ No newline at end of file + $ php chat.php \ No newline at end of file diff --git a/composer.json b/composer.json index 1ad9eed..549b7bf 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,6 @@ "php": ">=5.3.2" , "guzzle/guzzle": "2.5.*" , "symfony/http-foundation": "2.1.*" - , "react/event-loop": "dev-master" , "react/socket": "dev-master" } } \ No newline at end of file diff --git a/composer.lock b/composer.lock index 8846011..0bc2d55 100644 --- a/composer.lock +++ b/composer.lock @@ -1,5 +1,5 @@ { - "hash": "b7d2ee4e3fd11f2e9c862b6b2ca2372f", + "hash": "6651c947d3ce090d73c14dfff3877944", "packages": [ { "package": "evenement/evenement", @@ -13,12 +13,24 @@ { "package": "react/event-loop", "version": "dev-master", - "source-reference": "e9850fe37b04a34cb4d6b59861d3a6c680fb1aa1" + "source-reference": "cc341b109feae06fa33dff7486aa567e3b9d1406" }, { "package": "react/socket", "version": "dev-master", - "source-reference": "a2b7d74eef48f9fec44bf727d19b0385101b62a2" + "source-reference": "6801c6d8653e1999cb34b235cdb4b3a287e4d528" + }, + { + "package": "symfony/event-dispatcher", + "version": "dev-master", + "source-reference": "0b58a4019befc0bd038bc0ec0165101d5dd31754", + "alias-pretty-version": "2.1.x-dev", + "alias-version": "2.1.9999999.9999999-dev" + }, + { + "package": "symfony/event-dispatcher", + "version": "dev-master", + "source-reference": "0b58a4019befc0bd038bc0ec0165101d5dd31754" }, { "package": "symfony/event-dispatcher", @@ -27,11 +39,6 @@ "alias-pretty-version": "2.1.x-dev", "alias-version": "2.1.9999999.9999999-dev" }, - { - "package": "symfony/event-dispatcher", - "version": "dev-master", - "source-reference": "0c1ae4898196f5e96b79028d8d2f35de4b584659" - }, { "package": "symfony/http-foundation", "version": "dev-master", @@ -42,7 +49,14 @@ { "package": "symfony/http-foundation", "version": "dev-master", - "source-reference": "54c22f4bf8625303503a117dcc68544d3f8ac876" + "source-reference": "cf8e8324c68ce584525502702866485f17f1c8a5", + "alias-pretty-version": "2.1.x-dev", + "alias-version": "2.1.9999999.9999999-dev" + }, + { + "package": "symfony/http-foundation", + "version": "dev-master", + "source-reference": "cf8e8324c68ce584525502702866485f17f1c8a5" } ], "packages-dev": null, diff --git a/src/Ratchet/Server/IoServer.php b/src/Ratchet/Server/IoServer.php index daf9b12..8c2a487 100644 --- a/src/Ratchet/Server/IoServer.php +++ b/src/Ratchet/Server/IoServer.php @@ -6,7 +6,6 @@ use React\EventLoop\LoopInterface; use React\Socket\ServerInterface; use React\EventLoop\Factory as LoopFactory; use React\Socket\Server as Reactor; -use React\EventLoop\StreamSelectLoop; /** * Creates an open-ended socket to listen on a port for incomming connections. Events are delegated through this to attached applications @@ -45,16 +44,12 @@ class IoServer { } public static function factory(MessageComponentInterface $component, $port = 80, $address = '0.0.0.0') { - // Enable this after we fix a bug with libevent - // $loop = LoopFactory::create(); - - $loop = new StreamSelectLoop; + $loop = LoopFactory::create(); $socket = new Reactor($loop); $socket->listen($port, $address); - $server = new static($component, $socket, $loop); - return $server; + return new static($component, $socket, $loop); } public function run() { @@ -65,7 +60,7 @@ class IoServer { $conn->decor = new IoConnection($conn, $this); $conn->decor->resourceId = (int)$conn->socket; - $conn->decor->remoteAddress = '127.0.0.1'; // todo + $conn->decor->remoteAddress = $conn->getRemoteAddress(); $this->app->onOpen($conn->decor); diff --git a/tests/Ratchet/Tests/Server/IoServerTest.php b/tests/Ratchet/Tests/Server/IoServerTest.php new file mode 100644 index 0000000..141cbef --- /dev/null +++ b/tests/Ratchet/Tests/Server/IoServerTest.php @@ -0,0 +1,89 @@ +app = new Component; + + $loop = new StreamSelectLoop(0); + $this->reactor = new Server($loop); + $this->reactor->listen(0); + + $this->port = $this->reactor->getPort(); + $this->server = new IoServer($this->app, $this->reactor, $loop); + } + + public function testOnOpen() { + $client = stream_socket_client("tcp://localhost:{$this->port}"); + + $this->server->loop->tick(); + + $this->assertInstanceOf('\\Ratchet\\ConnectionInterface', $this->app->last['onOpen'][0]); + $this->assertTrue(is_string($this->app->last['onOpen'][0]->remoteAddress)); + $this->assertTrue(is_int($this->app->last['onOpen'][0]->resourceId)); + } + + public function testOnData() { + $msg = 'Hello World!'; + + $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1); + socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096); + socket_set_block($client); + socket_connect($client, 'localhost', $this->port); + + $this->server->loop->tick(); + + socket_write($client, $msg); + $this->server->loop->tick(); + + socket_shutdown($client, 1); + socket_shutdown($client, 0); + socket_close($client); + + usleep(5000); + + $this->server->loop->tick(); + + $this->assertEquals($msg, $this->app->last['onMessage'][1]); + } + + public function testOnClose() { + $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1); + socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096); + socket_set_block($client); + socket_connect($client, 'localhost', $this->port); + + $this->server->loop->tick(); + + socket_shutdown($client, 1); + socket_shutdown($client, 0); + socket_close($client); + + $this->server->loop->tick(); + + usleep(5000); + + $this->assertSame($this->app->last['onOpen'][0], $this->app->last['onClose'][0]); + } + + public function testFactory() { + $this->assertInstanceOf('\\Ratchet\\Server\\IoServer', IoServer::factory($this->app, 0)); + } +} \ No newline at end of file