ReactPHP-Dns
Dns
为ReactPHP提供的异步DNS解析。
DNS组件的主要目的是提供异步DNS解析。但是,它实际上是处理DNS消息的工具包,可以很容易地用于创建DNS服务器
基本用法
最基本的用法是通过解析器工厂创建解析器。你只需要给它一个名字,然后你就可以开始解析名字了,兄(xiong)弟(dei).
$loop = React\EventLoop\Factory::create();
$config = React\Dns\Config\Config::loadSystemConfigBlocking();
$server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
$factory = new React\Dns\Resolver\Factory();
$dns = $factory->create($server, $loop);
$dns->resolve('igor.io')->then(function ($ip) {
echo "Host: $ip\n";
});
$loop->run();
参阅第一个例子
Config
类可以被用作加载系统的默认配置。这是一个可能访问文件系统和块的操作。因此,理想情况下,该方法应该在循环开始前只执行一次,而在运行时不重复执行。注意,如果无法加载系统配置,该类可能返回空配置。因此,如果找不到任何名称,您可能希望应用上面的默认名称服务器。
注意,在创建解析实例时,工厂将从文件系统加载主机文件一次。理想情况下,这个方法应该在循环开始钱执行一次,而在运行时不再重复执行。
但还有更多。
缓存
你可以通过配置解析器用CachedExecutor来缓存结果:
$loop = React\EventLoop\Factory::create();
$config = React\Dns\Config\Config::loadSystemConfigBlocking();
$server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
$factory = new React\Dns\Resolver\Factory();
$dns = $factory->createCached($server, $loop);
$dns->resolve('igor.io')->then(function ($ip) {
echo "Host: $ip\n";
});
...
$dns->resolve('igor.io')->then(function ($ip) {
echo "Host: $ip\n";
});
$loop->run();
如果第一个调用在第二个调用之前返回,那么将只有一次查询被执行。第二次查询结果将从内存缓存中获得。这对多次查询相同主机名的长时间运行的脚本很有用。
参阅第三个例子。
自定义缓存适配器
默认情况下,上述操作将使用内存缓存。
你还可以指定一个自定义缓存实现CacheInterface来处理记录缓存:
$cache = new React\Cache\ArrayCache();
$loop = React\EventLoop\Factory::create();
$factory = new React\Dns\Resolver\Factory();
$dns = $factory->createCached('8.8.8.8', $loop, $cache);
请参阅wiki以了解可能的缓存实现。
解析器
resolve()
resolve(string $domain): PromiseInterface<string,Exception>
方法可以将给定的$domain
域名解析成一个IPv4地址(类型为查询)。
$resolver->resolve('reactphp.org')->then(function ($ip) {
echo 'IP for reactphp.org is ' . $ip . PHP_EOL;
});
这是这个包的主要方法之一。它将向你的DNS服务器发送一个给定$domain
域名的DNS查询,查询成功将返回一个唯一的IP地址。
如果DNS服务器发送的DNS响应消息包含此查询的多个IP地址,它将任意选一个IP地址响应。如果你想要获取全部的IP地址列表或者想发送不同类型的查询,你可以换用resolveAll()
方法。
如果DNS服务器发送的DNS相应包提示一个错误码,这个方法将抛出一个RecordNotFoundException
异常。它的消息和代码可用于检查响应代码。
如果DNS通讯失败,DNS服务器没有返回一个有效的响应消息包,它将抛出一个Exception
异常。
挂起的DNS查询,可以取消其挂起承诺,如下:
$promise = $resolver->resolve('reactphp.org');
$promise->cancel();
resolveAll()
resolveAll(string $host,int $type):PromiseInterface<array,Exception>
方法可以用于查询给予的域名的所有记录和查询类型。
$resolver->resolveAll('reactphp.org', Message::TYPE_A)->then(function ($ips) {
echo 'IPv4 addresses for reactphp.org ' . implode(', ', $ips) . PHP_EOL;
});
$resolver->resolveAll('reactphp.org', Message::TYPE_AAAA)->then(function ($ips) {
echo 'IPv6 addresses for reactphp.org ' . implode(', ', $ips) . PHP_EOL;
});
这是这个包的主要方法之一。它将向你的DNS服务器发送一个给定$domain
域名的DNS查询,查询成功将返回包含所有记录的列表。
如果DNS服务器发送一个包含一条或者多条记录的DNS响应消息包,这个方法将从响应中返回一个包含所有记录的列表。你可以用Message::TYPE_*
常量来控制发送哪种查询类型。注意这个方法通常返回一个记录值的列表,但是每条记录的类型由查询类型决定。例如,类型为A
的查询返回IPv4地址,类型为AAAA
的查询返回IPv6地址,主机名用于类型NS、CNAME和PTR查询,结构化数据用于其他查询。参阅Record
文档查看更多详情。
如果DNS服务器发送的DNS相应包提示一个错误码,这个方法将抛出一个RecordNotFoundException
异常。它的消息和代码可用于检查响应代码。
如果DNS通讯失败,DNS服务器没有返回一个有效的响应消息包,它将抛出一个Exception
异常。
挂起的DNS查询,可以取消其挂起承诺,如下:
$promise = $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA);
$promise->cancel();
高阶用法
UdpTransportExecutor
可以用UdpTransportExecutor
在UDP传输上发送DNS查询。
这是向你的DNS服务器发送DNS查询的主类,解析器内部用于实际的消息传输。
更高级的用法,可以直接使用该类。下面的例子,查询igor.io的IPv6地址。
$loop = Factory::create();
$executor = new UdpTransportExecutor($loop);
$executor->query(
'8.8.8.8:53',
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');
$loop->run();
参阅第四个例子
注意,这个执行器没有实现超时,因此你很可能希望将其与TimeoutExecutor
结合使用:
$executor = new TimeoutExecutor(
new UdpTransportExecutor($loop),
3.0,
$loop
);
也要注意,这个执行器用不可靠的UDP传输,而且它没有实现任何重试逻辑,因此你很可能希望将其与RetryExecutor
结合使用:
$executor =new RetryExecutor(
new TimeoutExecutor(
new UdpTransportExecutor($loop),
3.0,
$loop
)
)
在内部,这个类使用PHP的UDP套接字,并不纯粹出于组织原因利用react/datagram来避免两个包之间的循环依赖关系。高级组件应该利用Datagram组件,而不是从头重新实现这个套接字逻辑。
HostsFileExecutor
注意上面的UdpTransportExecutor
总是执行实际的DNS查询。如果您还想将hosts文件中的条目考虑在内,您可以使用以下代码:
$hosts = \React\Dns\Config\HostsFile::loadFromPathBlocking();
$executor = new UdpTransportExecutor($loop);
$executor = new HostsFileExecutor($hosts, $executor);
$executor->query(
'8.8.8.8:53',
new Query('localhost', Message::TYPE_A, Message::CLASS_IN)
);
安装
推荐使用composer安装这个库。
这将安装最新版本:
$ composer require react/dns:^0.4.15
有关版本升级的详细信息,请参阅变更日志。
这个项目的目标是在任何平台上运行,不需要任何PHP扩展,支持PHP5.3到PHP7+和HHVM版本。极力推荐在项目中使用PHP7+版本。
#Tests
要运行测试,你首先需要复制这个repo,然后通过composer安装所有依赖:
$ composer install
运行测试,到项目根目录然后运行:
$ php vendor/bin/phpunit
这个测试也包含很多依靠网络通信的方法集合测试。如果你不想运行这些,你可以像这样简单的跳过:
$ php vendor/bin/phpunit --exclude-group internet
License
MIT,查看协议文件