PHP套接字超时和阻塞

时间:2019-06-30 12:03:14

标签: php sockets

我无法理解套接字超时和阻塞的工作方式,以及这两者是否互连。

这是我的构造函数:

public function __construct(Options $options)
{
    $this->connection = stream_socket_client($options->fullSocketAddress());

    stream_set_blocking($this->connection, true);
    stream_set_timeout($this->connection, 0, $this->timeout);
}

socket timeout阅读手册开始,在流上设置超时。我最初的理解是超时是一个极限,套接字将尝试执行某项操作,然后超时。但是现实是,当同时使用stream_get_meta_data()检查套接字状态时,我得到以下信息:

(
    [timed_out] =>
    [blocked] => 1
    [eof] =>
    [stream_type] => tcp_socket/ssl
    [mode] => r+
    [unread_bytes] => 0
    [seekable] =>
)

这是在我收到第一个响应时发生的,对于每个后续响应,timed_out的值为1

因为最初我的超时值是1s,所以我认为服务器的响应速度很慢,但是将值增加到50s实际上会增加每个后续请求的等待时间,就好像超时是强制性等待一样时间,不是“最多”的等待时间?

关于这一点,我尝试使用套接字阻止状态。从关于socket blocking的手册中,我没有得到太多信息,因为它没有解释流被阻塞或不阻塞的含义。从我能理解的方式上搜集一些资源,据我所知将套接字设置为阻塞状态将等待服务器响应,并且只有在响应返回后,它才会继续处理其他请求。我认为我没有得到这种行为。

每次写时,我正在阅读。与套接字阻塞无关,写入似乎发生得更快。

public function send(string $xml)
{
    try {
        fwrite($this->connection, $xml);
        $this->options->getLogger()->logRequest(__METHOD__ . '::' . __LINE__ . " $xml");
        $this->checkSocketStatus();
    } catch (Exception $e) {
        $this->options->getLogger()->error(__METHOD__ . '::' . __LINE__ . " fwrite() failed " . $e->getMessage());
        return;
    }

    $this->receive();
}

public function receive()
{
    $response = '';
    while ($out = fgets($this->connection)) {
        $response .= $out;
    }

    if (empty($response)) {
        return;
    }

    $this->responseBuffer->write($response);
    $this->options->getLogger()->logResponse(__METHOD__ . '::' . __LINE__ . " $response");
}

是否有一种方法可以等待检查响应,并确保没有后续请求,除非获取了响应? sleep(1)可以快速解决问题,但不是我想要的。再次调用receive()函数在某种程度上也可以解决问题,但是程序开始表现出奇怪的现象,我想避免这种情况:

    if (empty($response)) {
        $this->receive();
        return;
    } 

此外,套接字超时和阻塞状态之间是否存在任何互连?

0 个答案:

没有答案