werkint/reactphp-socket-client

此包已被废弃且不再维护。作者建议使用 werkint/reactphp-socket-client 包。

基于 TCP/IP 和 SSL/TLS 的异步连接器。

v0.5.3 2016-12-24 11:19 UTC

README

Build Status Code Climate

基于 TCP/IP 和 SSL/TLS 的异步连接器。

简介

将此库视为 fsockopen()stream_socket_client() 的异步版本。

在实际向远程服务器发送和接收数据之前,您必须与远程端建立连接。通过互联网/网络建立此连接需要一些时间,因为它需要完成几个步骤

  1. 通过 DNS (+缓存) 解析远程目标主机名
  2. 与远程目标 IP:端口的 TCP 握手(2 个往返)
  3. 可选:在新的连接上启用 SSL/TLS

用法

为了使用此项目,您需要以下 React boilerplate 代码来初始化主循环。

$loop = React\EventLoop\Factory::create();

ConnectorInterface

ConnectorInterface 负责提供建立流式连接的接口,例如普通的 TCP/IP 连接。

这是本包中定义的主要接口,并在 React 的庞大生态系统中使用。

大多数高级组件(如 HTTP、数据库或其他网络服务客户端)接受实现此接口的实例以创建其与底层网络服务的 TCP/IP 连接。这通常是通过依赖注入完成的,因此实际上交换此实现与其他接口的实现非常简单。

该接口仅提供一种方法

create()

create(string $host, int $port): PromiseInterface<Stream, Exception> 方法可用于建立流式连接。它返回一个 Promise,该 Promise 要么满足一个 Stream,要么拒绝一个 Exception

$connector->create('google.com', 443)->then(
    function (Stream $stream) {
        // connection successfully established
    },
    function (Exception $error) {
        // failed to connect due to $error
    }
);

返回的 Promise 应该被实现为可以在它仍然挂起时取消。取消挂起的 Promise 应该使用一个 Exception 拒绝其值。它应该根据适用性清理任何底层资源。

$promise = $connector->create($host, $port);

$promise->cancel();

异步 TCP/IP 连接

React\SocketClient\TcpConnector 类实现了 ConnectorInterface,并允许您创建到任何 IP-端口号组合的纯文本 TCP/IP 连接

$tcpConnector = new React\SocketClient\TcpConnector($loop);

$tcpConnector->create('127.0.0.1', 80)->then(function (React\Stream\Stream $stream) {
    $stream->write('...');
    $stream->end();
});

$loop->run();

请参阅第一个示例

可以通过取消挂起的 Promise 来取消挂起的连接尝试

$promise = $tcpConnector->create($host, $port);

$promise->cancel();

在挂起的 Promise 上调用 cancel() 将关闭底层的套接字资源,从而取消挂起的 TCP/IP 连接,并拒绝结果 Promise。

您可以可选地像这样向构造函数传递额外的 套接字上下文选项

$tcpConnector = new React\SocketClient\TcpConnector($loop, array(
    'bindto' => '192.168.0.1:0'
));

请注意,此类只允许您连接到IP端口组合。如果您想连接到主机名端口组合,请参阅以下章节。

DNS解析

DnsConnector类实现了ConnectorInterface接口,允许您创建到任何主机名端口组合的明文TCP/IP连接。

它是通过装饰一个给定的TcpConnector实例来实现的,这样它首先通过DNS(如果适用)查找给定的域名,然后与解析后的目标IP地址建立底层的TCP/IP连接。

请确保按照以下方式设置您的DNS解析器和底层的TCP连接器

$dnsResolverFactory = new React\Dns\Resolver\Factory();
$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);

$dnsConnector = new React\SocketClient\DnsConnector($tcpConnector, $dns);

$dnsConnector->create('www.google.com', 80)->then(function (React\Stream\Stream $stream) {
    $stream->write('...');
    $stream->end();
});

$loop->run();

请参阅第一个示例

可以通过取消挂起的 Promise 来取消挂起的连接尝试

$promise = $dnsConnector->create($host, $port);

$promise->cancel();

在挂起的承诺上调用cancel()将取消底层的DNS查找和/或底层的TCP/IP连接,并拒绝生成的承诺。

为了向后兼容,可以使用传统的Connector类。它非常类似于较新的DnsConnector,但需要按照以下方式设置

$connector = new React\SocketClient\Connector($loop, $dns);

$connector->create('www.google.com', 80)->then($callback);

异步SSL/TLS连接

SecureConnector类实现了ConnectorInterface接口,允许您创建到任何主机名端口组合的安全TLS(以前称为SSL)连接。

它是通过装饰一个给定的DnsConnector实例来实现的,这样它首先创建一个明文TCP/IP连接,然后在此流上启用TLS加密。

$secureConnector = new React\SocketClient\SecureConnector($dnsConnector, $loop);

$secureConnector->create('www.google.com', 443)->then(function (React\Stream\Stream $stream) {
    $stream->write("GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n");
    ...
});

$loop->run();

请参阅第二个示例

可以通过取消挂起的 Promise 来取消挂起的连接尝试

$promise = $secureConnector->create($host, $port);

$promise->cancel();

在挂起的承诺上调用cancel()将取消底层的TCP/IP连接和/或SSL/TLS协商,并拒绝生成的承诺。

您可以可选地像这样向构造函数传递额外的SSL上下文选项

$secureConnector = new React\SocketClient\SecureConnector($dnsConnector, $loop, array(
    'verify_peer' => false,
    'verify_peer_name' => false
));

高级用法:内部,SecureConnector必须在底层的流资源上设置所需的上下文选项。因此,它应该在连接器堆栈中的某个位置与TcpConnector一起使用,以便为每个流资源分配一个空的上下文资源。否则,可能会出现一些难以追踪的竞争条件,因为所有流资源都将使用单个、共享的默认上下文资源。

连接超时

TimeoutConnector类实现了ConnectorInterface接口,允许您向任何现有的连接器实例添加超时处理。

它是通过装饰任何给定的ConnectorInterface实例并启动一个计时器来实现的,该计时器将自动拒绝和取消任何底层连接尝试,如果它花费了太长时间。

$timeoutConnector = new React\SocketClient\TimeoutConnector($connector, 3.0, $loop);

$timeoutConnector->create('google.com', 80)->then(function (React\Stream\Stream $stream) {
    // connection succeeded within 3.0 seconds
});

请参阅任何示例

可以通过取消挂起的 Promise 来取消挂起的连接尝试

$promise = $timeoutConnector->create($host, $port);

$promise->cancel();

在挂起的承诺上调用cancel()将取消底层的连接尝试,取消计时器并拒绝生成的承诺。

Unix域套接字

UnixConnector类实现了ConnectorInterface接口,允许您连接到Unix域套接字(UDS)路径,如下所示

$connector = new React\SocketClient\UnixConnector($loop);

$connector->create('/tmp/demo.sock')->then(function (React\Stream\Stream $stream) {
    $stream->write("HELLO\n");
});

$loop->run();

连接到Unix域套接字是一个原子操作,即它的承诺将立即解决(解决或拒绝)。因此,在结果承诺上调用 cancel() 没有作用。

安装

安装此库的推荐方法是通过Composer新手使用Composer?

这将安装最新支持的版本

$ composer require react/socket-client:^0.5.3

有关版本升级的更多详细信息,请参阅CHANGELOG

测试

要运行测试套件,您需要PHPUnit。转到项目根目录并运行

$ phpunit

测试套件还包括一些可选的集成测试,这些测试在TCP/IP套接字服务器上运行,并在其前面有一个可选的TLS/SSL终止代理。底层的TCP/IP套接字服务器将自动启动,而TLS/SSL终止代理则需要像这样启动并启用

$ stunnel -f -p stunnel.pem -d 6001 -r 6000 &
$ TEST_SECURE=6001 TEST_PLAIN=6000 phpunit

有关如何设置TLS/SSL终止代理和所需的证书文件(stunnel.pem)的详细信息,请参阅Travis配置。如果您不确定。