Example #1
0
 protected function connectToAddress(string $address, float $timeout, bool $encrypt)
 {
     $url = \sprintf('%s://%s', $this->protocol, $address);
     $errno = null;
     $errstr = null;
     $context = \stream_context_create(\array_replace_recursive($this->options, ['socket' => ['connect' => $address]]));
     $socket = @\stream_socket_client($url, $errno, $errstr, $timeout ?: null, \STREAM_CLIENT_CONNECT | \STREAM_CLIENT_ASYNC_CONNECT, $context);
     if (!\is_resource($socket)) {
         throw new SocketException(\sprintf('Could not connect to "%s" (%s): [%s] %s', $url, $this->peer, $errno, \trim($errstr)));
     }
     try {
         \stream_set_blocking($socket, false);
         \stream_set_read_buffer($socket, 0);
         \stream_set_write_buffer($socket, 0);
         if ($this->tcpNoDelay) {
             Socket::setTcpNoDelay($socket, true);
         }
         if ($encrypt) {
             yield from $this->encryptSocketClient($socket, $timeout);
         } else {
             (yield new AwaitWrite($socket, $timeout));
         }
         return $socket;
     } catch (\Throwable $e) {
         Socket::shutdown($socket);
         throw $e;
     }
 }
Example #2
0
 /**
  * Set TCP nodelay setting (nagle algorithm) of the underlying socket resource.
  * 
  * @param bool $nodelay
  * @return bool
  */
 public function setTcpNoDelay(bool $nodelay) : bool
 {
     if (\is_resource($this->socket)) {
         return Socket::setTcpNoDelay($this->socket, $nodelay);
     }
     return false;
 }
Example #3
0
 protected function listenLoop(callable $callback, float $timeout) : \Generator
 {
     while (true) {
         try {
             (yield $this->waiting = new AwaitRead($this->socket));
         } finally {
             $this->waiting = null;
         }
         $socket = @\stream_socket_accept($this->socket, 0);
         if (false !== $socket) {
             \stream_set_blocking($socket, false);
             \stream_set_read_buffer($socket, 0);
             \stream_set_write_buffer($socket, 0);
             if ($this->tcpNoDelay) {
                 Socket::setTcpNoDelay($socket, true);
             }
             // Offload handling the client to another coroutine keeping the listen loop running.
             new Coroutine($this->handleClient($callback, $socket, $timeout), true);
         }
     }
 }