Skip to content

Commit d32c497

Browse files
authored
Merge pull request #129 from clue-labs/default-loop
Simplify usage by supporting new default loop and new Socket API
2 parents 2946751 + 1f9f4d1 commit d32c497

File tree

7 files changed

+64
-74
lines changed

7 files changed

+64
-74
lines changed

README.md

+34-37
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,23 @@ An asynchronous WebSocket client in PHP
1010

1111
#### Usage
1212
Pawl as a standalone app: Connect to an echo server, send a message, display output, close connection:
13+
1314
```php
1415
<?php
1516

16-
require __DIR__ . '/vendor/autoload.php';
17-
18-
\Ratchet\Client\connect('wss://echo.websocket.org:443')->then(function($conn) {
19-
$conn->on('message', function($msg) use ($conn) {
20-
echo "Received: {$msg}\n";
21-
$conn->close();
22-
});
17+
require __DIR__ . '/vendor/autoload.php';
2318

24-
$conn->send('Hello World!');
25-
}, function ($e) {
26-
echo "Could not connect: {$e->getMessage()}\n";
19+
\Ratchet\Client\connect('wss://echo.websocket.org:443')->then(function($conn) {
20+
$conn->on('message', function($msg) use ($conn) {
21+
echo "Received: {$msg}\n";
22+
$conn->close();
2723
});
28-
```
2924

30-
---
25+
$conn->send('Hello World!');
26+
}, function ($e) {
27+
echo "Could not connect: {$e->getMessage()}\n";
28+
});
29+
```
3130

3231
#### Classes
3332

@@ -57,31 +56,29 @@ A more in-depth example using explicit interfaces: Requesting sub-protocols, and
5756
```php
5857
<?php
5958

60-
require __DIR__ . '/vendor/autoload.php';
61-
62-
$loop = \React\EventLoop\Factory::create();
63-
$reactConnector = new \React\Socket\Connector($loop, [
64-
'dns' => '8.8.8.8',
65-
'timeout' => 10
66-
]);
67-
$connector = new \Ratchet\Client\Connector($loop, $reactConnector);
68-
69-
$connector('ws://127.0.0.1:9000', ['protocol1', 'subprotocol2'], ['Origin' => 'http://localhost'])
70-
->then(function(\Ratchet\Client\WebSocket $conn) {
71-
$conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
72-
echo "Received: {$msg}\n";
73-
$conn->close();
74-
});
75-
76-
$conn->on('close', function($code = null, $reason = null) {
77-
echo "Connection closed ({$code} - {$reason})\n";
78-
});
79-
80-
$conn->send('Hello World!');
81-
}, function(\Exception $e) use ($loop) {
82-
echo "Could not connect: {$e->getMessage()}\n";
83-
$loop->stop();
59+
require __DIR__ . '/vendor/autoload.php';
60+
61+
$reactConnector = new \React\Socket\Connector([
62+
'dns' => '8.8.8.8',
63+
'timeout' => 10
64+
]);
65+
$loop = \React\EventLoop\Loop::get();
66+
$connector = new \Ratchet\Client\Connector($loop, $reactConnector);
67+
68+
$connector('ws://127.0.0.1:9000', ['protocol1', 'subprotocol2'], ['Origin' => 'http://localhost'])
69+
->then(function(\Ratchet\Client\WebSocket $conn) {
70+
$conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
71+
echo "Received: {$msg}\n";
72+
$conn->close();
73+
});
74+
75+
$conn->on('close', function($code = null, $reason = null) {
76+
echo "Connection closed ({$code} - {$reason})\n";
8477
});
8578

86-
$loop->run();
79+
$conn->send('Hello World!');
80+
}, function(\Exception $e) use ($loop) {
81+
echo "Could not connect: {$e->getMessage()}\n";
82+
$loop->stop();
83+
});
8784
```

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
}
1212
, "require": {
1313
"php": ">=5.4"
14-
, "react/socket": "^1.0 || ^0.8 || ^0.7"
1514
, "evenement/evenement": "^3.0 || ^2.0"
1615
, "ratchet/rfc6455": "^0.3"
16+
, "react/socket": "^1.9"
1717
}
1818
, "require-dev": {
1919
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8"

src/Connector.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace Ratchet\Client;
33
use Ratchet\RFC6455\Handshake\ClientNegotiator;
4+
use React\EventLoop\Loop;
45
use React\EventLoop\LoopInterface;
56
use React\Socket\ConnectionInterface;
67
use React\Socket\ConnectorInterface;
@@ -15,14 +16,15 @@ class Connector {
1516
protected $_secureConnector;
1617
protected $_negotiator;
1718

18-
public function __construct(LoopInterface $loop, ConnectorInterface $connector = null) {
19+
public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null) {
20+
$this->_loop = $loop ?: Loop::get();
21+
1922
if (null === $connector) {
20-
$connector = new \React\Socket\Connector($loop, [
23+
$connector = new \React\Socket\Connector([
2124
'timeout' => 20
22-
]);
25+
], $this->_loop);
2326
}
2427

25-
$this->_loop = $loop;
2628
$this->_connector = $connector;
2729
$this->_negotiator = new ClientNegotiator;
2830
}

src/functions.php

-16
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<?php
22
namespace Ratchet\Client;
33
use React\EventLoop\LoopInterface;
4-
use React\EventLoop\Factory as ReactFactory;
5-
use React\EventLoop\Timer\Timer;
64

75
/**
86
* @param string $url
@@ -12,22 +10,8 @@
1210
* @return \React\Promise\PromiseInterface<\Ratchet\Client\WebSocket>
1311
*/
1412
function connect($url, array $subProtocols = [], $headers = [], LoopInterface $loop = null) {
15-
$loop = $loop ?: ReactFactory::create();
16-
1713
$connector = new Connector($loop);
1814
$connection = $connector($url, $subProtocols, $headers);
1915

20-
$runHasBeenCalled = false;
21-
22-
$loop->addTimer(Timer::MIN_INTERVAL, function () use (&$runHasBeenCalled) {
23-
$runHasBeenCalled = true;
24-
});
25-
26-
register_shutdown_function(function() use ($loop, &$runHasBeenCalled) {
27-
if (!$runHasBeenCalled) {
28-
$loop->run();
29-
}
30-
});
31-
3216
return $connection;
3317
}

tests/autobahn/runner.php

+9-11
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66

77
define('AGENT', 'Pawl/0.3');
88

9-
$loop = React\EventLoop\Factory::create();
10-
11-
$connFactory = function() use ($loop) {
12-
$connector = new Ratchet\Client\Connector($loop);
9+
$connFactory = function() {
10+
$connector = new Ratchet\Client\Connector();
1311

1412
return function($url) use ($connector) {
1513
return $connector('ws://127.0.0.1:9001' . $url);
@@ -29,14 +27,14 @@
2927
return $futureNum->promise();
3028
}, function($e) {
3129
echo "Could not connect to test server: {$e->getMessage()}\n";
32-
})->then(function($numOfCases) use ($connector, $loop) {
30+
})->then(function($numOfCases) use ($connector) {
3331
echo "Running {$numOfCases} test cases\n\n";
3432

3533
$allCases = new Deferred;
3634

3735
$i = 0;
3836

39-
$runNextCase = function() use (&$runNextCase, &$i, $numOfCases, $allCases, $connector, $loop) {
37+
$runNextCase = function() use (&$runNextCase, &$i, $numOfCases, $allCases, $connector) {
4038
$i++;
4139

4240
if ($i > (int)$numOfCases->getPayload()) {
@@ -59,11 +57,11 @@
5957
$runNextCase();
6058

6159
return $allCases->promise();
62-
})->then(function() use ($connector, $loop) {
63-
$connector('/updateReports?agent=' . AGENT)->then(function(WebSocket $conn) use ($loop) {
60+
})->then(function() use ($connector) {
61+
$connector('/updateReports?agent=' . AGENT)->then(function(WebSocket $conn) {
6462
echo "\nDone!\n";
65-
$conn->on('close', [$loop, 'stop']);
63+
$conn->on('close', function () {
64+
\React\EventLoop\Loop::stop();
65+
});
6666
});
6767
});
68-
69-
$loop->run();

tests/unit/ConnectorTest.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@
22

33
use PHPUnit\Framework\TestCase;
44
use Ratchet\Client\Connector;
5-
use React\EventLoop\Factory;
5+
use React\EventLoop\Loop;
66
use React\Promise\RejectedPromise;
77
use React\Promise\Promise;
88

99
class ConnectorTest extends TestCase
1010
{
11+
public function testConstructWithoutLoopAssignsLoopAutomatically()
12+
{
13+
$factory = new Connector();
14+
15+
$ref = new \ReflectionProperty($factory, '_loop');
16+
$ref->setAccessible(true);
17+
$loop = $ref->getValue($factory);
18+
19+
$this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
20+
}
21+
1122
public function uriDataProvider() {
1223
return [
1324
['ws://127.0.0.1', 'tcp://127.0.0.1:80'],
@@ -21,7 +32,7 @@ public function uriDataProvider() {
2132
* @dataProvider uriDataProvider
2233
*/
2334
public function testSecureConnectionUsesTlsScheme($uri, $expectedConnectorUri) {
24-
$loop = Factory::create();
35+
$loop = Loop::get();
2536

2637
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
2738

tests/unit/RequestUriTest.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ function uriDataProvider() {
2929
* @dataProvider uriDataProvider
3030
*/
3131
function testGeneratedRequestUri($uri, $expectedRequestUri) {
32-
$loop = Factory::create();
33-
34-
$connector = new Connector($loop);
32+
$connector = new Connector();
3533

3634
$generateRequest = self::getPrivateClassMethod('\Ratchet\Client\Connector', 'generateRequest');
3735
$request = $generateRequest->invokeArgs($connector, [$uri, [], []]);

0 commit comments

Comments
 (0)