protected function createClient($endpoint, $config = [])
    {
        $ssl = $this->config['ssl'];
        $name = $this->config['ssl_name'];
        $verifySign = $this->config['ssl_verify_sign'];
        $verifyPeer = $this->config['ssl_verify_peer'];
        $verifyDepth = $this->config['ssl_verify_depth'];

        $context = [];
        $context['socket'] = [
            'connect' => $endpoint
        ];
        $context['ssl'] = [
            'capture_peer_cert' => true,
            'capture_peer_chain' => true,
            'capture_peer_cert_chain' => true,
            'allow_self_signed' => !$verifySign,
            'verify_peer' => $verifyPeer,
            'verify_peer_name' => $verifyPeer,
            'verify_depth' => $verifyDepth,
            'SNI_enabled' => $name !== '',
            'SNI_server_name' => $name,
            'peer_name' => $name,
            'disable_compression' => true,
            'honor_cipher_order' => true,
        ];

        if ($ssl && isset($config['ssl_cafile']))
        {
            $context['ssl']['cafile'] = $config['ssl_cafile'];
        }

        if ($ssl && isset($config['ssl_capath']))
        {
            $context['ssl']['capath'] = $config['ssl_capath'];
        }

        $context = stream_context_create($context);
        // Error reporting suppressed since stream_socket_client() emits an E_WARNING on failure.
        $socket = @stream_socket_client(
            $endpoint,
            $errno,
            $errstr,
            0, // Timeout does not apply for async connect.
            STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT,
            $context
        );

        if (!$socket || $errno > 0)
        {
            throw new LogicException(
                sprintf('Could not connect socket [%s] because of error [%d; %s]', $endpoint, $errno, $errstr)
            );
        }

        stream_set_blocking($socket, false);

        return $socket;
    }