Skip to content

Commit 991c1b6

Browse files
authored
Merge pull request #260 from clue-labs/default-loop
Simplify usage by supporting new default loop
2 parents 5d39e3f + b471dc7 commit 991c1b6

32 files changed

+363
-177
lines changed

README.md

Lines changed: 120 additions & 80 deletions
Large diffs are not rendered by default.

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828
"require": {
2929
"php": ">=5.3.0",
3030
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
31-
"react/dns": "^1.7",
32-
"react/event-loop": "^1.0 || ^0.5",
31+
"react/dns": "^1.8",
32+
"react/event-loop": "^1.2",
3333
"react/promise": "^2.6.0 || ^1.2.1",
3434
"react/promise-timer": "^1.4.0",
35-
"react/stream": "^1.1"
35+
"react/stream": "^1.2"
3636
},
3737
"require-dev": {
3838
"clue/block-react": "^1.2",

examples/01-echo-server.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@
1616
// $ php examples/01-echo-server.php unix:///tmp/server.sock
1717
// $ nc -U /tmp/server.sock
1818

19-
use React\EventLoop\Factory;
2019
use React\Socket\Server;
2120
use React\Socket\ConnectionInterface;
2221

2322
require __DIR__ . '/../vendor/autoload.php';
2423

25-
$loop = Factory::create();
26-
27-
$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
24+
$server = new Server(isset($argv[1]) ? $argv[1] : 0, null, array(
2825
'tls' => array(
2926
'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
3027
)
@@ -38,5 +35,3 @@
3835
$server->on('error', 'printf');
3936

4037
echo 'Listening on ' . $server->getAddress() . PHP_EOL;
41-
42-
$loop->run();

examples/02-chat-server.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
// $ php examples/02-chat-server.php unix:///tmp/server.sock
1717
// $ nc -U /tmp/server.sock
1818

19-
use React\EventLoop\Factory;
2019
use React\Socket\Server;
2120
use React\Socket\ConnectionInterface;
2221
use React\Socket\LimitingServer;
2322

2423
require __DIR__ . '/../vendor/autoload.php';
2524

26-
$loop = Factory::create();
27-
28-
$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
25+
$server = new Server(isset($argv[1]) ? $argv[1] : 0, null, array(
2926
'tls' => array(
3027
'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
3128
)
@@ -55,5 +52,3 @@
5552
$server->on('error', 'printf');
5653

5754
echo 'Listening on ' . $server->getAddress() . PHP_EOL;
58-
59-
$loop->run();

examples/03-http-server.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,12 @@
2929
// $ php examples/03-http-server.php unix:///tmp/server.sock
3030
// $ nc -U /tmp/server.sock
3131

32-
use React\EventLoop\Factory;
3332
use React\Socket\Server;
3433
use React\Socket\ConnectionInterface;
3534

3635
require __DIR__ . '/../vendor/autoload.php';
3736

38-
$loop = Factory::create();
39-
40-
$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
37+
$server = new Server(isset($argv[1]) ? $argv[1] : 0, null, array(
4138
'tls' => array(
4239
'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
4340
)
@@ -53,5 +50,3 @@
5350
$server->on('error', 'printf');
5451

5552
echo 'Listening on ' . strtr($server->getAddress(), array('tcp:' => 'http:', 'tls:' => 'https:')) . PHP_EOL;
56-
57-
$loop->run();

examples/11-http-client.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,14 @@
1111
// $ php examples/11-http-client.php
1212
// $ php examples/11-http-client.php reactphp.org
1313

14-
use React\EventLoop\Factory;
1514
use React\Socket\Connector;
1615
use React\Socket\ConnectionInterface;
1716

1817
$host = isset($argv[1]) ? $argv[1] : 'www.google.com';
1918

2019
require __DIR__ . '/../vendor/autoload.php';
2120

22-
$loop = Factory::create();
23-
$connector = new Connector($loop);
21+
$connector = new Connector();
2422

2523
$connector->connect($host. ':80')->then(function (ConnectionInterface $connection) use ($host) {
2624
$connection->on('data', function ($data) {
@@ -32,5 +30,3 @@
3230

3331
$connection->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n");
3432
}, 'printf');
35-
36-
$loop->run();

examples/12-https-client.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,14 @@
1111
// $ php examples/12-https-client.php
1212
// $ php examples/12-https-client.php reactphp.org
1313

14-
use React\EventLoop\Factory;
1514
use React\Socket\Connector;
1615
use React\Socket\ConnectionInterface;
1716

1817
$host = isset($argv[1]) ? $argv[1] : 'www.google.com';
1918

2019
require __DIR__ . '/../vendor/autoload.php';
2120

22-
$loop = Factory::create();
23-
$connector = new Connector($loop);
21+
$connector = new Connector();
2422

2523
$connector->connect('tls://' . $host . ':443')->then(function (ConnectionInterface $connection) use ($host) {
2624
$connection->on('data', function ($data) {
@@ -32,5 +30,3 @@
3230

3331
$connection->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n");
3432
}, 'printf');
35-
36-
$loop->run();

examples/21-netcat-client.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
// $ php examples/21-netcat-client.php www.google.com:80
99
// $ php examples/21-netcat-client.php tls://www.google.com:443
1010

11-
use React\EventLoop\Factory;
1211
use React\Socket\Connector;
1312
use React\Socket\ConnectionInterface;
1413
use React\Stream\ReadableResourceStream;
@@ -31,13 +30,12 @@
3130
exit(1);
3231
}
3332

34-
$loop = Factory::create();
35-
$connector = new Connector($loop);
33+
$connector = new Connector();
3634

37-
$stdin = new ReadableResourceStream(STDIN, $loop);
35+
$stdin = new ReadableResourceStream(STDIN);
3836
$stdin->pause();
39-
$stdout = new WritableResourceStream(STDOUT, $loop);
40-
$stderr = new WritableResourceStream(STDERR, $loop);
37+
$stdout = new WritableResourceStream(STDOUT);
38+
$stderr = new WritableResourceStream(STDERR);
4139

4240
$stderr->write('Connecting' . PHP_EOL);
4341

@@ -64,5 +62,3 @@
6462
}, function ($error) use ($stderr) {
6563
$stderr->write('Connection ERROR: ' . $error . PHP_EOL);
6664
});
67-
68-
$loop->run();

examples/22-http-client.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
// $ php examples/22-http-client.php
1414
// $ php examples/22-http-client.php https://reactphp.org/
1515

16-
use React\EventLoop\Factory;
1716
use React\Socket\ConnectionInterface;
1817
use React\Socket\Connector;
1918
use React\Stream\WritableResourceStream;
@@ -32,8 +31,7 @@
3231
exit(1);
3332
}
3433

35-
$loop = Factory::create();
36-
$connector = new Connector($loop);
34+
$connector = new Connector();
3735

3836
if (!isset($parts['port'])) {
3937
$parts['port'] = $parts['scheme'] === 'https' ? 443 : 80;
@@ -49,12 +47,10 @@
4947
$resource .= '?' . $parts['query'];
5048
}
5149

52-
$stdout = new WritableResourceStream(STDOUT, $loop);
50+
$stdout = new WritableResourceStream(STDOUT);
5351

5452
$connector->connect($target)->then(function (ConnectionInterface $connection) use ($resource, $host, $stdout) {
5553
$connection->pipe($stdout);
5654

5755
$connection->write("GET $resource HTTP/1.0\r\nHost: $host\r\n\r\n");
5856
}, 'printf');
59-
60-
$loop->run();

examples/91-benchmark-server.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,18 @@
2222
// $ nc -N -U /tmp/server.sock
2323
// $ dd if=/dev/zero bs=1M count=1000 | nc -N -U /tmp/server.sock
2424

25-
use React\EventLoop\Factory;
2625
use React\Socket\Server;
2726
use React\Socket\ConnectionInterface;
2827

2928
require __DIR__ . '/../vendor/autoload.php';
3029

31-
$loop = Factory::create();
32-
33-
$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
30+
$server = new Server(isset($argv[1]) ? $argv[1] : 0, null, array(
3431
'tls' => array(
3532
'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
3633
)
3734
));
3835

39-
$server->on('connection', function (ConnectionInterface $connection) use ($loop) {
36+
$server->on('connection', function (ConnectionInterface $connection) {
4037
echo '[connected]' . PHP_EOL;
4138

4239
// count the number of bytes received from this connection
@@ -56,5 +53,3 @@
5653
$server->on('error', 'printf');
5754

5855
echo 'Listening on ' . $server->getAddress() . PHP_EOL;
59-
60-
$loop->run();

src/Connector.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use React\Dns\Config\Config as DnsConfig;
66
use React\Dns\Resolver\Factory as DnsFactory;
77
use React\Dns\Resolver\ResolverInterface;
8+
use React\EventLoop\Loop;
89
use React\EventLoop\LoopInterface;
910

1011
/**
@@ -26,8 +27,9 @@ final class Connector implements ConnectorInterface
2627
{
2728
private $connectors = array();
2829

29-
public function __construct(LoopInterface $loop, array $options = array())
30+
public function __construct(LoopInterface $loop = null, array $options = array())
3031
{
32+
$loop = $loop ?: Loop::get();
3133
// apply default options if not explicitly given
3234
$options += array(
3335
'tcp' => true,

src/FixedUriConnector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* ```php
1313
* $connector = new React\Socket\FixedUriConnector(
1414
* 'unix:///var/run/docker.sock',
15-
* new React\Socket\UnixConnector($loop)
15+
* new React\Socket\UnixConnector()
1616
* );
1717
*
1818
* // destination will be ignored, actually connects to Unix domain socket

src/HappyEyeBallsConnector.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace React\Socket;
44

55
use React\Dns\Resolver\ResolverInterface;
6+
use React\EventLoop\Loop;
67
use React\EventLoop\LoopInterface;
78
use React\Promise;
89

@@ -12,9 +13,18 @@ final class HappyEyeBallsConnector implements ConnectorInterface
1213
private $connector;
1314
private $resolver;
1415

15-
public function __construct(LoopInterface $loop, ConnectorInterface $connector, ResolverInterface $resolver)
16+
public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null, ResolverInterface $resolver = null)
1617
{
17-
$this->loop = $loop;
18+
// $connector and $resolver arguments are actually required, marked
19+
// optional for technical reasons only. Nullable $loop without default
20+
// requires PHP 7.1, null default is also supported in legacy PHP
21+
// versions, but required parameters are not allowed after arguments
22+
// with null default. Mark all parameters optional and check accordingly.
23+
if ($connector === null || $resolver === null) {
24+
throw new \InvalidArgumentException('Missing required $connector or $resolver argument');
25+
}
26+
27+
$this->loop = $loop ?: Loop::get();
1828
$this->connector = $connector;
1929
$this->resolver = $resolver;
2030
}
@@ -34,7 +44,7 @@ public function connect($uri)
3444
}
3545

3646
$host = \trim($parts['host'], '[]');
37-
47+
3848
// skip DNS lookup / URI manipulation if this URI already contains an IP
3949
if (false !== \filter_var($host, \FILTER_VALIDATE_IP)) {
4050
return $this->connector->connect($uri);

src/SecureConnector.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace React\Socket;
44

5+
use React\EventLoop\Loop;
56
use React\EventLoop\LoopInterface;
67
use React\Promise;
78
use BadMethodCallException;
@@ -14,10 +15,10 @@ final class SecureConnector implements ConnectorInterface
1415
private $streamEncryption;
1516
private $context;
1617

17-
public function __construct(ConnectorInterface $connector, LoopInterface $loop, array $context = array())
18+
public function __construct(ConnectorInterface $connector, LoopInterface $loop = null, array $context = array())
1819
{
1920
$this->connector = $connector;
20-
$this->streamEncryption = new StreamEncryption($loop, false);
21+
$this->streamEncryption = new StreamEncryption($loop ?: Loop::get(), false);
2122
$this->context = $context;
2223
}
2324

src/SecureServer.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace React\Socket;
44

55
use Evenement\EventEmitter;
6+
use React\EventLoop\Loop;
67
use React\EventLoop\LoopInterface;
78
use BadMethodCallException;
89
use UnexpectedValueException;
@@ -15,8 +16,8 @@
1516
* TCP/IP connections and then performs a TLS handshake for each connection.
1617
*
1718
* ```php
18-
* $server = new React\Socket\TcpServer(8000, $loop);
19-
* $server = new React\Socket\SecureServer($server, $loop, array(
19+
* $server = new React\Socket\TcpServer(8000);
20+
* $server = new React\Socket\SecureServer($server, null, array(
2021
* // tls context options here…
2122
* ));
2223
* ```
@@ -67,8 +68,8 @@ final class SecureServer extends EventEmitter implements ServerInterface
6768
* PEM encoded certificate file:
6869
*
6970
* ```php
70-
* $server = new React\Socket\TcpServer(8000, $loop);
71-
* $server = new React\Socket\SecureServer($server, $loop, array(
71+
* $server = new React\Socket\TcpServer(8000);
72+
* $server = new React\Socket\SecureServer($server, null, array(
7273
* 'local_cert' => 'server.pem'
7374
* ));
7475
* ```
@@ -82,8 +83,8 @@ final class SecureServer extends EventEmitter implements ServerInterface
8283
* like this:
8384
*
8485
* ```php
85-
* $server = new React\Socket\TcpServer(8000, $loop);
86-
* $server = new React\Socket\SecureServer($server, $loop, array(
86+
* $server = new React\Socket\TcpServer(8000);
87+
* $server = new React\Socket\SecureServer($server, null, array(
8788
* 'local_cert' => 'server.pem',
8889
* 'passphrase' => 'secret'
8990
* ));
@@ -94,6 +95,12 @@ final class SecureServer extends EventEmitter implements ServerInterface
9495
* and/or PHP version.
9596
* Passing unknown context options has no effect.
9697
*
98+
* This class takes an optional `LoopInterface|null $loop` parameter that can be used to
99+
* pass the event loop instance to use for this object. You can use a `null` value
100+
* here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
101+
* This value SHOULD NOT be given unless you're sure you want to explicitly use a
102+
* given event loop instance.
103+
*
97104
* Advanced usage: Despite allowing any `ServerInterface` as first parameter,
98105
* you SHOULD pass a `TcpServer` instance as first parameter, unless you
99106
* know what you're doing.
@@ -109,13 +116,13 @@ final class SecureServer extends EventEmitter implements ServerInterface
109116
* then close the underlying connection.
110117
*
111118
* @param ServerInterface|TcpServer $tcp
112-
* @param LoopInterface $loop
119+
* @param ?LoopInterface $loop
113120
* @param array $context
114121
* @throws BadMethodCallException for legacy HHVM < 3.8 due to lack of support
115122
* @see TcpServer
116123
* @link https://www.php.net/manual/en/context.ssl.php for TLS context options
117124
*/
118-
public function __construct(ServerInterface $tcp, LoopInterface $loop, array $context)
125+
public function __construct(ServerInterface $tcp, LoopInterface $loop = null, array $context = array())
119126
{
120127
if (!\function_exists('stream_socket_enable_crypto')) {
121128
throw new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)'); // @codeCoverageIgnore
@@ -127,7 +134,7 @@ public function __construct(ServerInterface $tcp, LoopInterface $loop, array $co
127134
);
128135

129136
$this->tcp = $tcp;
130-
$this->encryption = new StreamEncryption($loop);
137+
$this->encryption = new StreamEncryption($loop ?: Loop::get());
131138
$this->context = $context;
132139

133140
$that = $this;

0 commit comments

Comments
 (0)