Skip to content

Improve documentation and add API docs (docblocks) #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Among others, multicast networking is the basis for:
* [Factory](#factory)
* [createSender()](#createsender)
* [createReceiver()](#createreceiver)
* [Socket](#socket)
* [SocketInterface](#socketinterface)
* [Install](#install)
* [Tests](#tests)
* [License](#license)
Expand Down Expand Up @@ -48,7 +48,7 @@ See also the [examples](examples).

### Factory

The `Factory` is responsible for creating your [`Socket`](#socket) instances.
The `Factory` is responsible for creating your [`SocketInterface`](#socketinterface) instances.
It also registers everything with the main [`EventLoop`](https://github.com/reactphp/event-loop#usage).

```php
Expand All @@ -58,7 +58,9 @@ $factory = new Factory($loop);

#### createSender()

The `createSender()` method can be used to create a socket capable of sending outgoing multicast datagrams and receiving incoming unicast responses. It returns a [`Socket`](#socket) instance.
The `createSender(): SocketInterface` method can be used to
create a socket capable of sending outgoing multicast datagrams and receiving
incoming unicast responses. It returns a [`SocketInterface`](#socketinterface) instance.

```php
$socket = $factory->createSender();
Expand All @@ -73,11 +75,13 @@ $socket->on('message', function ($data, $address) {
```

This method works on PHP versions as old as PHP 5.3 (and up), as its socket API has always been
[level 1 multicast conformant](http://www.tldp.org/HOWTO/Multicast-HOWTO-2.html#ss2.2).
[level 1 multicast conformant](https://www.tldp.org/HOWTO/Multicast-HOWTO-2.html#ss2.2).

#### createReceiver()

The `createReceiver($address)` method can be used to create a socket capable of receiving incoming multicast datagrams and sending outgoing unicast or multicast datagrams. It returns a [`Socket`](#socket) instance.
The `createReceiver(string $address): SocketInterface` method can be used to
create a socket capable of receiving incoming multicast datagrams and sending
outgoing unicast or multicast datagrams. It returns a [`SocketInterface`](#socketinterface) instance.

```php
$socket = $factory->createReceiver('224.10.20.30:4050');
Expand All @@ -91,10 +95,10 @@ $socket->on('message', function ($data, $remote) use ($socket) {
});
```

This method requires PHP 5.4 (or up) and ext-sockets.
This method requires PHP 5.4 (or up) and `ext-sockets`.
Otherwise, it will throw a `BadMethodCallException`.
This is a requirement because receiving multicast datagrams requires a
[level 2 multicast conformant](http://www.tldp.org/HOWTO/Multicast-HOWTO-2.html#ss2.2)
[level 2 multicast conformant](https://www.tldp.org/HOWTO/Multicast-HOWTO-2.html#ss2.2)
socket API.
The required multicast socket options and constants have been added with
[PHP 5.4](http://php.net/manual/en/migration54.global-constants.php) (and up).
Expand All @@ -104,12 +108,14 @@ to the newer stream based networking API.
Internally, this library uses a workaround to create stream based sockets
and then sets the required socket options on its underlying low level socket
resource.
This is done because React PHP is built around the general purpose stream based API
This is done because ReactPHP is built around the general purpose stream based API
and has only somewhat limited support for the low level socket API.

### Socket
### SocketInterface

The [`Factory`](#factory) creates instances of the `React\Datagram\Socket` class from the [react/datagram](https://github.com/reactphp/datagram) package.
The [`Factory`](#factory) creates instances of the `React\Datagram\SocketInterface`
from the [react/datagram](https://github.com/reactphp/datagram) package.
This means that you can use all its normal methods like so:

```php
$socket->send($message, $address);
Expand Down Expand Up @@ -140,6 +146,10 @@ extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
HHVM.
It's *highly recommended to use PHP 7+* for this project.

The [`createSender()`](#createsender) method works on all supported platforms
without any additional requirements. However, the [`createReceiver()`](#createreceiver)
method requires PHP 5.4 (or up) and `ext-sockets`. See above for more details.

## Tests

To run the test suite, you first need to clone this repo and then install all
Expand Down
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"phpunit/phpunit": "^6.0 || ^5.7 || ^4.8.35"
},
"suggest": {
"php": "PHP 5.4+ is required for listening on multicast addresses (socket options to send IGMP announcements)",
"ext-sockets": "Low level socket API required for listening on multicast addresses (socket options to send IGMP announcements)"
"ext-sockets": "Requires PHP 5.4+ and the low level socket API for listening on multicast addresses (socket options to send IGMP announcements)"
}
}
6 changes: 3 additions & 3 deletions examples/ssdp.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* UPNP simple service discovery protocol (SSDP)
* UPnP simple service discovery protocol (SSDP)
*/

use Clue\React\Multicast\Factory;
Expand All @@ -14,7 +14,7 @@
$sender = $factory->createSender();

// dump all incoming messages
$sender->on('message', function ($data, $remote) use ($hex) {
$sender->on('message', function ($data, $remote) {
echo 'Received from ' . $remote . PHP_EOL;
echo $data . PHP_EOL;
});
Expand All @@ -24,7 +24,7 @@
$sender->pause();
});

// send a discovery message that all upnp/ssdp aware devices will respond to
// send a discovery message that all UPnP/SSDP aware devices will respond to
$data = "M-SEARCH * HTTP/1.1\r\n";
$data .= "HOST: " . $address . "\r\n";
$data .= "MAN: \"ssdp:discover\"\r\n";
Expand Down
70 changes: 70 additions & 0 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,44 @@ class Factory
{
private $loop;

/**
* The `Factory` is responsible for creating your [`SocketInterface`](#socketinterface) instances.
* It also registers everything with the main [`EventLoop`](https://github.com/reactphp/event-loop#usage).
*
* ```php
* $loop = React\EventLoop\Factory::create();
* $factory = new Factory($loop);
* ```
*
* @param LoopInterface $loop
*/
public function __construct(LoopInterface $loop)
{
$this->loop = $loop;
}

/**
* Creates a socket capable of sending outgoing multicast datagrams and receiving
* incoming unicast responses. It returns a [`SocketInterface`](#socketinterface) instance.
*
* ```php
* $socket = $factory->createSender();
*
* // send a multicast message to everybody listening on the given address
* $socket->send('hello?', '224.10.20.30:4050');
*
* // report incoming unicast replies
* $socket->on('message', function ($data, $address) {
* echo 'received ' . strlen($data) . ' bytes from ' . $address . PHP_EOL;
* });
* ```
*
* This method works on PHP versions as old as PHP 5.3 (and up), as its socket API has always been
* [level 1 multicast conformant](https://www.tldp.org/HOWTO/Multicast-HOWTO-2.html#ss2.2).
*
* @return \React\Datagram\SocketInterface
* @throws RuntimeException
*/
public function createSender()
{
$stream = @stream_socket_server('udp://0.0.0.0:0', $errno, $errstr, STREAM_SERVER_BIND);
Expand All @@ -26,6 +59,43 @@ public function createSender()
return new DatagramSocket($this->loop, $stream);
}

/**
* Creates a socket capable of receiving incoming multicast datagrams and sending
* outgoing unicast or multicast datagrams. It returns a [`SocketInterface`](#socketinterface) instance.
*
* ```php
* $socket = $factory->createReceiver('224.10.20.30:4050');
*
* // report incoming multicast messages
* $socket->on('message', function ($data, $remote) use ($socket) {
* echo 'Sending back ' . strlen($data) . ' bytes to ' . $remote . PHP_EOL;
*
* // send a unicast reply to the remote
* $socket->send($data, $remote);
* });
* ```
*
* This method requires PHP 5.4 (or up) and `ext-sockets`.
* Otherwise, it will throw a `BadMethodCallException`.
* This is a requirement because receiving multicast datagrams requires a
* [level 2 multicast conformant](https://www.tldp.org/HOWTO/Multicast-HOWTO-2.html#ss2.2)
* socket API.
* The required multicast socket options and constants have been added with
* [PHP 5.4](http://php.net/manual/en/migration54.global-constants.php) (and up).
* These options are only available to the low level socket API (ext-sockets), not
* to the newer stream based networking API.
*
* Internally, this library uses a workaround to create stream based sockets
* and then sets the required socket options on its underlying low level socket
* resource.
* This is done because ReactPHP is built around the general purpose stream based API
* and has only somewhat limited support for the low level socket API.
*
* @param string $address
* @return \React\Datagram\SocketInterface
* @throws BadMethodCallException
* @throws RuntimeException
*/
public function createReceiver($address)
{
if (!defined('MCAST_JOIN_GROUP')) {
Expand Down