Skip to content

Commit 80ece13

Browse files
committed
Merge pull request #5 from clue/address
Unify socket addresses (string URIs instead of host+port)
2 parents f4ff4eb + f814144 commit 80ece13

File tree

7 files changed

+57
-42
lines changed

7 files changed

+57
-42
lines changed

Datagram/Factory.php

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@ public function __construct(LoopInterface $loop, Resolver $resolver = null)
1919
$this->resolver = $resolver;
2020
}
2121

22-
public function createClient($host, $port)
22+
public function createClient($address)
2323
{
2424
$factory = $this;
2525
$loop = $this->loop;
2626

27-
return $this->resolve($host)->then(function ($ip) use ($loop, $port, $factory) {
28-
$address = $factory->createAddress($ip, $port);
29-
$socket = stream_socket_client('udp://' . $address, $errno, $errstr);
27+
return $this->resolveAddress($address)->then(function ($address) use ($loop) {
28+
$socket = stream_socket_client($address, $errno, $errstr);
3029
if (!$socket) {
3130
throw new Exception('Unable to create client socket: ' . $errstr, $errno);
3231
}
@@ -35,15 +34,13 @@ public function createClient($host, $port)
3534
});
3635
}
3736

38-
public function createServer($port, $host = '127.0.0.1')
37+
public function createServer($address)
3938
{
4039
$factory = $this;
4140
$loop = $this->loop;
4241

43-
return $this->resolve($host)->then(function ($ip) use ($loop, $port, $factory) {
44-
$address = $factory->createAddress($ip, $port);
45-
46-
$socket = stream_socket_server("udp://" . $address, $errno, $errstr, STREAM_SERVER_BIND);
42+
return $this->resolveAddress($address)->then(function ($address) use ($loop) {
43+
$socket = stream_socket_server($address, $errno, $errstr, STREAM_SERVER_BIND);
4744
if (!$socket) {
4845
throw new Exception('Unable to create server socket: ' . $errstr, $errno);
4946
}
@@ -52,7 +49,39 @@ public function createServer($port, $host = '127.0.0.1')
5249
});
5350
}
5451

55-
protected function resolve($host)
52+
protected function resolveAddress($address)
53+
{
54+
if (strpos($address, '://') === false) {
55+
$address = 'udp://' . $address;
56+
}
57+
$parts = parse_url($address);
58+
59+
if (!$parts || !isset($parts['host'])) {
60+
return When::resolve($address);
61+
}
62+
63+
// remove square brackets for IPv6 addresses
64+
$host = trim($parts['host'], '[]');
65+
66+
return $this->resolveHost($host)->then(function ($host) use ($parts) {
67+
$address = $parts['scheme'] . '://';
68+
69+
if (isset($parts['port']) && strpos($host, ':') !== false) {
70+
// enclose IPv6 address in square brackets if a port will be appended
71+
$host = '[' . $host . ']';
72+
}
73+
74+
$address .= $host;
75+
76+
if (isset($parts['port'])) {
77+
$address .= ':' . $parts['port'];
78+
}
79+
80+
return $address;
81+
});
82+
}
83+
84+
protected function resolveHost($host)
5685
{
5786
// there's no need to resolve if the host is already given as an IP address
5887
if (false !== filter_var($host, FILTER_VALIDATE_IP)) {
@@ -64,17 +93,8 @@ protected function resolve($host)
6493
}
6594

6695
if ($this->resolver === null) {
67-
return When::reject(\Exception('No resolver given in order to get IP address for given hostname'));
96+
return When::reject(new Exception('No resolver given in order to get IP address for given hostname'));
6897
}
6998
return $this->resolver->resolve($host);
7099
}
71-
72-
public function createAddress($host, $port)
73-
{
74-
if (strpos($host, ':') !== false) {
75-
// enclose IPv6 address in square brackets
76-
$host = '[' . $host . ']';
77-
}
78-
return $host . ':' . $port;
79-
}
80100
}

Datagram/Socket.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,18 @@ public function __construct(LoopInterface $loop, $socket, Buffer $buffer = null)
3333
$this->resume();
3434
}
3535

36-
public function getAddress()
36+
public function getLocalAddress()
3737
{
3838
if ($this->socket !== false) {
3939
return stream_socket_get_name($this->socket, false);
4040
}
4141
}
4242

43-
public function getPort()
43+
public function getRemoteAddress()
4444
{
45-
$address = $this->getAddress();
46-
return (int)substr($address, strrpos($address, ':') + 1);
47-
}
48-
49-
public function getHost()
50-
{
51-
$address = $this->getAddress();
52-
return trim(substr($address, 0, strrpos($address, ':')), '[]');
45+
if ($this->socket !== false) {
46+
return stream_socket_get_name($this->socket, true);
47+
}
5348
}
5449

5550
public function send($data, $remoteAddress = null)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ $loop = React\EventLoop\Factory::create();
1212

1313
$factory = new Datagram\Factory($loop);
1414

15-
$factory->createClient('localhost', 1234)->then(function (Datagram\Socket $client) use ($loop) {
15+
$factory->createClient('localhost:1234')->then(function (Datagram\Socket $client) {
1616
$client->send('first');
1717

1818
$client->on('message', function($message, $serverAddress, $client) {

example/client.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
$factory = new Datagram\Factory($loop, $resolver);
1111

12-
$factory->createClient('localhost', 1234)->then(function (Datagram\Socket $client) use ($loop) {
12+
$factory->createClient('localhost:1234')->then(function (Datagram\Socket $client) use ($loop) {
1313
$client->send('first');
1414

1515
$client->on('message', function($message, $serverAddress, $client) {

example/server.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
$factory = new Datagram\Factory($loop);
88

9-
$factory->createServer(1234)->then(function (Datagram\Socket $server) {
9+
$factory->createServer('localhost:1234')->then(function (Datagram\Socket $server) {
1010
$server->on('message', function($message, $address, $server) {
1111
$server->send('hello ' . $address . '! echo: ' . $message, $address);
1212

tests/FactoryTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function setUp()
1616

1717
public function testCreateClient()
1818
{
19-
$promise = $this->factory->createClient('127.0.0.1', 12345);
19+
$promise = $this->factory->createClient('127.0.0.1:12345');
2020

2121
$capturedClient = $this->getValueFromResolvedPromise($promise);
2222
$this->assertInstanceOf('Datagram\Socket', $capturedClient);
@@ -26,7 +26,7 @@ public function testCreateClient()
2626

2727
public function testCreateClientLocalhost()
2828
{
29-
$promise = $this->factory->createClient('localhost', 12345);
29+
$promise = $this->factory->createClient('localhost:12345');
3030

3131
$capturedClient = $this->getValueFromResolvedPromise($promise);
3232
$this->assertInstanceOf('Datagram\Socket', $capturedClient);
@@ -36,7 +36,7 @@ public function testCreateClientLocalhost()
3636

3737
public function testCreateClientIpv6()
3838
{
39-
$promise = $this->factory->createClient('::1', 12345);
39+
$promise = $this->factory->createClient('[::1]:12345');
4040

4141
$capturedClient = $this->getValueFromResolvedPromise($promise);
4242
$this->assertInstanceOf('Datagram\Socket', $capturedClient);
@@ -46,7 +46,7 @@ public function testCreateClientIpv6()
4646

4747
public function testCreateServer()
4848
{
49-
$promise = $this->factory->createServer(12345, '127.0.0.1');
49+
$promise = $this->factory->createServer('127.0.0.1:12345');
5050

5151
$capturedServer = $this->getValueFromResolvedPromise($promise);
5252
$this->assertInstanceOf('Datagram\Socket', $capturedServer);

tests/SocketTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function setUp()
1616

1717
public function testCreateClientCloseWillNotBlock()
1818
{
19-
$promise = $this->factory->createClient('127.0.0.1', 12345);
19+
$promise = $this->factory->createClient('127.0.0.1:12345');
2020
$client = $this->getValueFromResolvedPromise($promise);
2121

2222
$client->send('test');
@@ -40,7 +40,7 @@ public function testClientCloseAgainWillNotBlock(Socket $client)
4040

4141
public function testCreateClientEndWillNotBlock()
4242
{
43-
$promise = $this->factory->createClient('127.0.0.1', 12345);
43+
$promise = $this->factory->createClient('127.0.0.1:12345');
4444
$client = $this->getValueFromResolvedPromise($promise);
4545

4646
$client->send('test');
@@ -77,7 +77,7 @@ public function testClientSendAfterEndIsNoop(Socket $client)
7777

7878
public function testClientSendHugeWillFail()
7979
{
80-
$promise = $this->factory->createClient('127.0.0.1', 12345);
80+
$promise = $this->factory->createClient('127.0.0.1:12345');
8181
$client = $this->getValueFromResolvedPromise($promise);
8282

8383
$client->send(str_repeat(1, 1024 * 1024));
@@ -89,10 +89,10 @@ public function testClientSendHugeWillFail()
8989

9090
public function testCreatePair()
9191
{
92-
$promise = $this->factory->createServer(0, '127.0.0.1');
92+
$promise = $this->factory->createServer('127.0.0.1:0');
9393
$server = $this->getValueFromResolvedPromise($promise);
9494

95-
$promise = $this->factory->createClient('127.0.0.1', $server->getPort());
95+
$promise = $this->factory->createClient($server->getLocalAddress());
9696
$client = $this->getValueFromResolvedPromise($promise);
9797

9898
$that = $this;

0 commit comments

Comments
 (0)