UdpTransportExecutor
in package
implements
ExecutorInterface
Send DNS queries over a UDP transport.
This is the main class that sends a DNS query to your DNS server and is used
internally by the Resolver
for the actual message transport.
For more advanced usages one can utilize this class directly.
The following example looks up the IPv6
address for igor.io
.
$executor = new UdpTransportExecutor('8.8.8.8:53');
$executor->query(
new Query($name, Message::TYPE_AAAA, Message::CLASS_IN)
)->then(function (Message $message) {
foreach ($message->answers as $answer) {
echo 'IPv6: ' . $answer->data . PHP_EOL;
}
}, 'printf');
See also the fourth example.
Note that this executor does not implement a timeout, so you will very likely
want to use this in combination with a TimeoutExecutor
like this:
$executor = new TimeoutExecutor(
new UdpTransportExecutor($nameserver),
3.0
);
Also note that this executor uses an unreliable UDP transport and that it
does not implement any retry logic, so you will likely want to use this in
combination with a RetryExecutor
like this:
$executor = new RetryExecutor(
new TimeoutExecutor(
new UdpTransportExecutor($nameserver),
3.0
)
);
Note that this executor is entirely async and as such allows you to execute
any number of queries concurrently. You should probably limit the number of
concurrent queries in your application or you're very likely going to face
rate limitations and bans on the resolver end. For many common applications,
you may want to avoid sending the same query multiple times when the first
one is still pending, so you will likely want to use this in combination with
a CoopExecutor
like this:
$executor = new CoopExecutor(
new RetryExecutor(
new TimeoutExecutor(
new UdpTransportExecutor($nameserver),
3.0
)
)
);
Internally, this class uses PHP's UDP sockets and does not take advantage of react/datagram purely for organizational reasons to avoid a cyclic dependency between the two packages. Higher-level components should take advantage of the Datagram component instead of reimplementing this socket logic from scratch.
Table of Contents
Interfaces
Properties
- $dumper : mixed
- $loop : mixed
- $maxPacketSize : int
- maximum UDP packet size to send and receive
- $nameserver : mixed
- $parser : mixed
Methods
- __construct() : mixed
- query() : PromiseInterface<string|int, Message>
- Executes a query and will return a response message
Properties
$dumper
private
mixed
$dumper
$loop
private
mixed
$loop
$maxPacketSize
maximum UDP packet size to send and receive
private
int
$maxPacketSize
= 512
$nameserver
private
mixed
$nameserver
$parser
private
mixed
$parser
Methods
__construct()
public
__construct(string $nameserver[, LoopInterface|null $loop = null ]) : mixed
Parameters
- $nameserver : string
- $loop : LoopInterface|null = null
query()
Executes a query and will return a response message
public
query(Query $query) : PromiseInterface<string|int, Message>
It returns a Promise which either fulfills with a response
React\Dns\Model\Message
on success or rejects with an Exception
if
the query is not successful. A response message may indicate an error
condition in its rcode
, but this is considered a valid response message.
$executor->query($query)->then(
function (React\Dns\Model\Message $response) {
// response message successfully received
var_dump($response->rcode, $response->answers);
},
function (Exception $error) {
// failed to query due to $error
}
);
The returned Promise MUST be implemented in such a way that it can be cancelled when it is still pending. Cancelling a pending promise MUST reject its value with an Exception. It SHOULD clean up any underlying resources and references as applicable.
$promise = $executor->query($query);
$promise->cancel();
Parameters
- $query : Query