| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- <?php
- namespace React\Dns\Query;
- use React\Promise\Promise;
- /**
- * Send DNS queries over a UDP or TCP/IP stream transport.
- *
- * This class will automatically choose the correct transport protocol to send
- * a DNS query to your DNS server. It will always try to send it over the more
- * efficient UDP transport first. If this query yields a size related issue
- * (truncated messages), it will retry over a streaming TCP/IP transport.
- *
- * For more advanced usages one can utilize this class directly.
- * The following example looks up the `IPv6` address for `reactphp.org`.
- *
- * ```php
- * $executor = new SelectiveTransportExecutor($udpExecutor, $tcpExecutor);
- *
- * $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');
- * ```
- *
- * Note that this executor only implements the logic to select the correct
- * transport for the given DNS query. Implementing the correct transport logic,
- * implementing timeouts and any retry logic is left up to the given executors,
- * see also [`UdpTransportExecutor`](#udptransportexecutor) and
- * [`TcpTransportExecutor`](#tcptransportexecutor) for more details.
- *
- * 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:
- *
- * ```php
- * $executor = new CoopExecutor(
- * new SelectiveTransportExecutor(
- * $datagramExecutor,
- * $streamExecutor
- * )
- * );
- * ```
- */
- class SelectiveTransportExecutor implements ExecutorInterface
- {
- private $datagramExecutor;
- private $streamExecutor;
- public function __construct(ExecutorInterface $datagramExecutor, ExecutorInterface $streamExecutor)
- {
- $this->datagramExecutor = $datagramExecutor;
- $this->streamExecutor = $streamExecutor;
- }
- public function query(Query $query)
- {
- $stream = $this->streamExecutor;
- $pending = $this->datagramExecutor->query($query);
- return new Promise(function ($resolve, $reject) use (&$pending, $stream, $query) {
- $pending->then(
- $resolve,
- function ($e) use (&$pending, $stream, $query, $resolve, $reject) {
- if ($e->getCode() === (\defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 90)) {
- $pending = $stream->query($query)->then($resolve, $reject);
- } else {
- $reject($e);
- }
- }
- );
- }, function () use (&$pending) {
- $pending->cancel();
- $pending = null;
- });
- }
- }
|