Skip to content

Commit 22d3b31

Browse files
authored
Merge pull request #263 from clue-labs/socketserver
Add new `SocketServer` and deprecate `Server` to avoid class name collisions
2 parents 92fb72d + 24f4abc commit 22d3b31

File tree

9 files changed

+467
-93
lines changed

9 files changed

+467
-93
lines changed

README.md

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ handle multiple concurrent connections without blocking.
3030
* [pause()](#pause)
3131
* [resume()](#resume)
3232
* [close()](#close)
33-
* [Server](#server)
33+
* [SocketServer](#socketserver)
3434
* [Advanced server usage](#advanced-server-usage)
3535
* [TcpServer](#tcpserver)
3636
* [SecureServer](#secureserver)
@@ -58,7 +58,7 @@ handle multiple concurrent connections without blocking.
5858
Here is a server that closes the connection if you send it anything:
5959

6060
```php
61-
$socket = new React\Socket\Server('127.0.0.1:8080');
61+
$socket = new React\Socket\SocketServer('127.0.0.1:8080');
6262

6363
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
6464
$connection->write("Hello " . $connection->getRemoteAddress() . "!\n");
@@ -214,7 +214,7 @@ The `connection` event will be emitted whenever a new connection has been
214214
established, i.e. a new client connects to this server socket:
215215

216216
```php
217-
$server->on('connection', function (React\Socket\ConnectionInterface $connection) {
217+
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
218218
echo 'new connection' . PHP_EOL;
219219
});
220220
```
@@ -228,7 +228,7 @@ The `error` event will be emitted whenever there's an error accepting a new
228228
connection from a client.
229229

230230
```php
231-
$server->on('error', function (Exception $e) {
231+
$socket->on('error', function (Exception $e) {
232232
echo 'error: ' . $e->getMessage() . PHP_EOL;
233233
});
234234
```
@@ -243,7 +243,7 @@ The `getAddress(): ?string` method can be used to
243243
return the full address (URI) this server is currently listening on.
244244

245245
```php
246-
$address = $server->getAddress();
246+
$address = $socket->getAddress();
247247
echo 'Server listening on ' . $address . PHP_EOL;
248248
```
249249

@@ -260,7 +260,7 @@ If this is a TCP/IP based server and you only want the local port, you may
260260
use something like this:
261261

262262
```php
263-
$address = $server->getAddress();
263+
$address = $socket->getAddress();
264264
$port = parse_url($address, PHP_URL_PORT);
265265
echo 'Server listening on port ' . $port . PHP_EOL;
266266
```
@@ -284,9 +284,9 @@ Once the server is paused, no futher `connection` events SHOULD
284284
be emitted.
285285

286286
```php
287-
$server->pause();
287+
$socket->pause();
288288

289-
$server->on('connection', assertShouldNeverCalled());
289+
$socket->on('connection', assertShouldNeverCalled());
290290
```
291291

292292
This method is advisory-only, though generally not recommended, the
@@ -309,10 +309,10 @@ resume accepting new incoming connections.
309309
Re-attach the socket resource to the EventLoop after a previous `pause()`.
310310

311311
```php
312-
$server->pause();
312+
$socket->pause();
313313

314-
Loop::addTimer(1.0, function () use ($server) {
315-
$server->resume();
314+
Loop::addTimer(1.0, function () use ($socket) {
315+
$socket->resume();
316316
});
317317
```
318318

@@ -329,90 +329,86 @@ This will stop listening for new incoming connections on this socket.
329329

330330
```php
331331
echo 'Shutting down server socket' . PHP_EOL;
332-
$server->close();
332+
$socket->close();
333333
```
334334

335335
Calling this method more than once on the same instance is a NO-OP.
336336

337-
### Server
337+
### SocketServer
338338

339-
The `Server` class is the main class in this package that implements the
339+
<a id="server"></a> <!-- legacy id -->
340+
341+
The `SocketServer` class is the main class in this package that implements the
340342
[`ServerInterface`](#serverinterface) and allows you to accept incoming
341343
streaming connections, such as plaintext TCP/IP or secure TLS connection streams.
342-
Connections can also be accepted on Unix domain sockets.
343344

344-
```php
345-
$server = new React\Socket\Server(8080);
346-
```
347-
348-
As above, the `$uri` parameter can consist of only a port, in which case the
349-
server will default to listening on the localhost address `127.0.0.1`,
350-
which means it will not be reachable from outside of this system.
351-
352-
In order to use a random port assignment, you can use the port `0`:
345+
In order to accept plaintext TCP/IP connections, you can simply pass a host
346+
and port combination like this:
353347

354348
```php
355-
$server = new React\Socket\Server(0);
356-
$address = $server->getAddress();
349+
$socket = new React\Socket\SocketServer('127.0.0.1:8080');
357350
```
358351

352+
Listening on the localhost address `127.0.0.1` means it will not be reachable from
353+
outside of this system.
359354
In order to change the host the socket is listening on, you can provide an IP
360-
address through the first parameter provided to the constructor, optionally
361-
preceded by the `tcp://` scheme:
355+
address of an interface or use the special `0.0.0.0` address to listen on all
356+
interfaces:
362357

363358
```php
364-
$server = new React\Socket\Server('192.168.0.1:8080');
359+
$socket = new React\Socket\SocketServer('0.0.0.0:8080');
365360
```
366361

367362
If you want to listen on an IPv6 address, you MUST enclose the host in square
368363
brackets:
369364

370365
```php
371-
$server = new React\Socket\Server('[::1]:8080');
366+
$socket = new React\Socket\SocketServer('[::1]:8080');
367+
```
368+
369+
In order to use a random port assignment, you can use the port `0`:
370+
371+
```php
372+
$socket = new React\Socket\SocketServer('127.0.0.1:0');
373+
$address = $socket->getAddress();
372374
```
373375

374376
To listen on a Unix domain socket (UDS) path, you MUST prefix the URI with the
375377
`unix://` scheme:
376378

377379
```php
378-
$server = new React\Socket\Server('unix:///tmp/server.sock');
380+
$socket = new React\Socket\SocketServer('unix:///tmp/server.sock');
379381
```
380382

381383
If the given URI is invalid, does not contain a port, any other scheme or if it
382384
contains a hostname, it will throw an `InvalidArgumentException`:
383385

384386
```php
385387
// throws InvalidArgumentException due to missing port
386-
$server = new React\Socket\Server('127.0.0.1');
388+
$socket = new React\Socket\SocketServer('127.0.0.1');
387389
```
388390

389391
If the given URI appears to be valid, but listening on it fails (such as if port
390392
is already in use or port below 1024 may require root access etc.), it will
391393
throw a `RuntimeException`:
392394

393395
```php
394-
$first = new React\Socket\Server(8080);
396+
$first = new React\Socket\SocketServer('127.0.0.1:8080');
395397

396398
// throws RuntimeException because port is already in use
397-
$second = new React\Socket\Server(8080);
399+
$second = new React\Socket\SocketServer('127.0.0.1:8080');
398400
```
399401

400402
> Note that these error conditions may vary depending on your system and/or
401403
configuration.
402404
See the exception message and code for more details about the actual error
403405
condition.
404406

405-
This class takes an optional `LoopInterface|null $loop` parameter that can be used to
406-
pass the event loop instance to use for this object. You can use a `null` value
407-
here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
408-
This value SHOULD NOT be given unless you're sure you want to explicitly use a
409-
given event loop instance.
410-
411407
Optionally, you can specify [TCP socket context options](https://www.php.net/manual/en/context.socket.php)
412408
for the underlying stream socket resource like this:
413409

414410
```php
415-
$server = new React\Socket\Server('[::1]:8080', null, array(
411+
$socket = new React\Socket\SocketServer('[::1]:8080', array(
416412
'tcp' => array(
417413
'backlog' => 200,
418414
'so_reuseport' => true,
@@ -426,8 +422,6 @@ $server = new React\Socket\Server('[::1]:8080', null, array(
426422
and/or PHP version.
427423
Passing unknown context options has no effect.
428424
The `backlog` context option defaults to `511` unless given explicitly.
429-
For BC reasons, you can also pass the TCP socket context options as a simple
430-
array without wrapping this in another array under the `tcp` key.
431425

432426
You can start a secure TLS (formerly known as SSL) server by simply prepending
433427
the `tls://` URI scheme.
@@ -438,7 +432,7 @@ which in its most basic form may look something like this if you're using a
438432
PEM encoded certificate file:
439433

440434
```php
441-
$server = new React\Socket\Server('tls://127.0.0.1:8080', null, array(
435+
$socket = new React\Socket\SocketServer('tls://127.0.0.1:8080', array(
442436
'tls' => array(
443437
'local_cert' => 'server.pem'
444438
)
@@ -454,7 +448,7 @@ If your private key is encrypted with a passphrase, you have to specify it
454448
like this:
455449

456450
```php
457-
$server = new React\Socket\Server('tls://127.0.0.1:8000', null, array(
451+
$socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', array(
458452
'tls' => array(
459453
'local_cert' => 'server.pem',
460454
'passphrase' => 'secret'
@@ -467,7 +461,7 @@ SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
467461
want to negotiate with the remote side:
468462

469463
```php
470-
$server = new React\Socket\Server('tls://127.0.0.1:8000', null, array(
464+
$socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', array(
471465
'tls' => array(
472466
'local_cert' => 'server.pem',
473467
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
@@ -488,7 +482,7 @@ Whenever a client connects, it will emit a `connection` event with a connection
488482
instance implementing [`ConnectionInterface`](#connectioninterface):
489483

490484
```php
491-
$server->on('connection', function (React\Socket\ConnectionInterface $connection) {
485+
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
492486
echo 'Plaintext connection from ' . $connection->getRemoteAddress() . PHP_EOL;
493487

494488
$connection->write('hello there!' . PHP_EOL);
@@ -498,10 +492,20 @@ $server->on('connection', function (React\Socket\ConnectionInterface $connection
498492

499493
See also the [`ServerInterface`](#serverinterface) for more details.
500494

501-
> Note that the `Server` class is a concrete implementation for TCP/IP sockets.
495+
This class takes an optional `LoopInterface|null $loop` parameter that can be used to
496+
pass the event loop instance to use for this object. You can use a `null` value
497+
here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
498+
This value SHOULD NOT be given unless you're sure you want to explicitly use a
499+
given event loop instance.
500+
501+
> Note that the `SocketServer` class is a concrete implementation for TCP/IP sockets.
502502
If you want to typehint in your higher-level protocol implementation, you SHOULD
503503
use the generic [`ServerInterface`](#serverinterface) instead.
504504

505+
> Changelog v1.9.0: This class has been added with an improved constructor signature
506+
as a replacement for the previous `Server` class in order to avoid any ambiguities.
507+
The previous name has been deprecated and should not be used anymore.
508+
505509
### Advanced server usage
506510

507511
#### TcpServer

examples/01-echo-server.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Just start this server and connect to it. Everything you send to it will be
44
// sent back to you.
55
//
6-
// $ php examples/01-echo-server.php 8000
6+
// $ php examples/01-echo-server.php 127.0.0.1:8000
77
// $ telnet localhost 8000
88
//
99
// You can also run a secure TLS echo server like this:
@@ -16,22 +16,19 @@
1616
// $ php examples/01-echo-server.php unix:///tmp/server.sock
1717
// $ nc -U /tmp/server.sock
1818

19-
use React\Socket\Server;
20-
use React\Socket\ConnectionInterface;
21-
2219
require __DIR__ . '/../vendor/autoload.php';
2320

24-
$server = new Server(isset($argv[1]) ? $argv[1] : 0, null, array(
21+
$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '127.0.0.1:0', array(
2522
'tls' => array(
2623
'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
2724
)
2825
));
2926

30-
$server->on('connection', function (ConnectionInterface $connection) {
27+
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
3128
echo '[' . $connection->getRemoteAddress() . ' connected]' . PHP_EOL;
3229
$connection->pipe($connection);
3330
});
3431

35-
$server->on('error', 'printf');
32+
$socket->on('error', 'printf');
3633

37-
echo 'Listening on ' . $server->getAddress() . PHP_EOL;
34+
echo 'Listening on ' . $socket->getAddress() . PHP_EOL;

examples/02-chat-server.php

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Just start this server and connect with any number of clients to it.
44
// Everything a client sends will be broadcasted to all connected clients.
55
//
6-
// $ php examples/02-chat-server.php 8000
6+
// $ php examples/02-chat-server.php 127.0.0.1:8000
77
// $ telnet localhost 8000
88
//
99
// You can also run a secure TLS chat server like this:
@@ -16,23 +16,19 @@
1616
// $ php examples/02-chat-server.php unix:///tmp/server.sock
1717
// $ nc -U /tmp/server.sock
1818

19-
use React\Socket\Server;
20-
use React\Socket\ConnectionInterface;
21-
use React\Socket\LimitingServer;
22-
2319
require __DIR__ . '/../vendor/autoload.php';
2420

25-
$server = new Server(isset($argv[1]) ? $argv[1] : 0, null, array(
21+
$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '127.0.0.1:0', array(
2622
'tls' => array(
2723
'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
2824
)
2925
));
3026

31-
$server = new LimitingServer($server, null);
27+
$socket = new React\Socket\LimitingServer($socket, null);
3228

33-
$server->on('connection', function (ConnectionInterface $client) use ($server) {
29+
$socket->on('connection', function (React\Socket\ConnectionInterface $client) use ($socket) {
3430
// whenever a new message comes in
35-
$client->on('data', function ($data) use ($client, $server) {
31+
$client->on('data', function ($data) use ($client, $socket) {
3632
// remove any non-word characters (just for the demo)
3733
$data = trim(preg_replace('/[^\w\d \.\,\-\!\?]/u', '', $data));
3834

@@ -43,12 +39,12 @@
4339

4440
// prefix with client IP and broadcast to all connected clients
4541
$data = trim(parse_url($client->getRemoteAddress(), PHP_URL_HOST), '[]') . ': ' . $data . PHP_EOL;
46-
foreach ($server->getConnections() as $connection) {
42+
foreach ($socket->getConnections() as $connection) {
4743
$connection->write($data);
4844
}
4945
});
5046
});
5147

52-
$server->on('error', 'printf');
48+
$socket->on('error', 'printf');
5349

54-
echo 'Listening on ' . $server->getAddress() . PHP_EOL;
50+
echo 'Listening on ' . $socket->getAddress() . PHP_EOL;

examples/03-http-server.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//
1313
// Just start this server and send a request to it:
1414
//
15-
// $ php examples/03-http-server.php 8000
15+
// $ php examples/03-http-server.php 127.0.0.1:8000
1616
// $ curl -v http://localhost:8000/
1717
// $ ab -n1000 -c10 http://localhost:8000/
1818
// $ docker run -it --rm --net=host jordi/ab ab -n1000 -c10 http://localhost:8000/
@@ -29,24 +29,21 @@
2929
// $ php examples/03-http-server.php unix:///tmp/server.sock
3030
// $ nc -U /tmp/server.sock
3131

32-
use React\Socket\Server;
33-
use React\Socket\ConnectionInterface;
34-
3532
require __DIR__ . '/../vendor/autoload.php';
3633

37-
$server = new Server(isset($argv[1]) ? $argv[1] : 0, null, array(
34+
$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '127.0.0.1:0', array(
3835
'tls' => array(
3936
'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
4037
)
4138
));
4239

43-
$server->on('connection', function (ConnectionInterface $connection) {
40+
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
4441
$connection->once('data', function () use ($connection) {
4542
$body = "<html><h1>Hello world!</h1></html>\r\n";
4643
$connection->end("HTTP/1.1 200 OK\r\nContent-Length: " . strlen($body) . "\r\nConnection: close\r\n\r\n" . $body);
4744
});
4845
});
4946

50-
$server->on('error', 'printf');
47+
$socket->on('error', 'printf');
5148

52-
echo 'Listening on ' . strtr($server->getAddress(), array('tcp:' => 'http:', 'tls:' => 'https:')) . PHP_EOL;
49+
echo 'Listening on ' . strtr($socket->getAddress(), array('tcp:' => 'http:', 'tls:' => 'https:')) . PHP_EOL;

0 commit comments

Comments
 (0)