Documentation

TcpTransportExecutor
in package
implements ExecutorInterface

Send DNS queries over a TCP/IP stream transport.

This is one of the main classes that send a DNS query to your DNS server.

For more advanced usages one can utilize this class directly. The following example looks up the IPv6 address for reactphp.org.

$executor = new TcpTransportExecutor('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 example #92.

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 TcpTransportExecutor($nameserver),
    3.0
);

Unlike the UdpTransportExecutor, this class uses a reliable TCP/IP transport, so you do not necessarily have to implement any retry logic.

Note that this executor is entirely async and as such allows you to execute queries concurrently. The first query will establish a TCP/IP socket connection to the DNS server which will be kept open for a short period. Additional queries will automatically reuse this existing socket connection to the DNS server, will pipeline multiple requests over this single connection and will keep an idle connection open for a short period. The initial TCP/IP connection overhead may incur a slight delay if you only send occasional queries – when sending a larger number of concurrent queries over an existing connection, it becomes increasingly more efficient and avoids creating many concurrent sockets like the UDP-based executor. You may still want to limit the number of (concurrent) queries in your application or you may be facing 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 TimeoutExecutor(
        new TcpTransportExecutor($nameserver),
        3.0
    )
);

Internally, this class uses PHP's TCP/IP sockets and does not take advantage of react/socket purely for organizational reasons to avoid a cyclic dependency between the two packages. Higher-level components should take advantage of the Socket component instead of reimplementing this socket logic from scratch.

Table of Contents

Interfaces

ExecutorInterface

Properties

$dumper  : mixed
$idlePeriod  : float
Maximum idle time when socket is current unused (i.e. no pending queries outstanding)
$idleTimer  : TimerInterface|null
$loop  : mixed
$names  : array<string|int, string>
$nameserver  : mixed
$parser  : mixed
$pending  : array<string|int, Deferred>
$readBuffer  : mixed
$readChunk  : string
$readPending  : mixed
$socket  : resource|null
$writeBuffer  : mixed
$writePending  : mixed

Methods

__construct()  : mixed
query()  : PromiseInterface<string|int, Message>
Executes a query and will return a response message

Properties

$idlePeriod

Maximum idle time when socket is current unused (i.e. no pending queries outstanding)

private float $idlePeriod = 0.001

If a new query is to be sent during the idle period, we can reuse the existing socket without having to wait for a new socket connection. This uses a rather small, hard-coded value to not keep any unneeded sockets open and to not keep the loop busy longer than needed.

A future implementation may take advantage of edns-tcp-keepalive to keep the socket open for longer periods. This will likely require explicit configuration because this may consume additional resources and also keep the loop busy for longer than expected in some applications.

Tags
link
https://tools.ietf.org/html/rfc7766#section-6.2.1
link
https://tools.ietf.org/html/rfc7828

Methods

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
Return values
PromiseInterface<string|int, Message>

        
On this page

Search results