`ReverseConnectSession` and `ReverseConnectClientFactory`
ReverseConnectSession and ReverseConnectClientFactory — the handoff types that turn a validated ReverseHello into a fully connected php-opcua/opcua-client Client.
These are the two types that bridge a successful accept() to the
standard php-opcua/opcua-client connection lifecycle.
ReverseConnectSession
Fully qualified name:
PhpOpcua\Client\ExtReverseConnect\ReverseConnectSession. Immutable
readonly value object.
final readonly class ReverseConnectSession
{
public function __construct(
public string $serverUri,
public string $endpointUrl,
public mixed $socket, // resource — live TCP stream
) {}
}
| Property | Meaning |
|---|---|
$serverUri |
The ServerUri the validator accepted — guaranteed non-empty and present in the whitelist. |
$endpointUrl |
The EndpointUrl the server announced, validated to start with opc.tcp:// and be non-empty. |
$socket |
Live blocking stream socket in CONNECTED state, RHE frame already consumed. |
The session takes ownership of the socket. In normal usage you pass
the session to
ReverseConnectClientFactory::buildClient(),
which wraps the socket into a transport whose close() will
fclose() it. If you do not call the factory (because you are
plugging the socket into something else), you are responsible for
closing it.
ReverseConnectClientFactory
Fully qualified name:
PhpOpcua\Client\ExtReverseConnect\ReverseConnectClientFactory.
public function buildClient(
ReverseConnectSession $session,
?Closure $configure = null,
?float $readTimeout = null,
): \PhpOpcua\Client\Client;
What it does, in order:
- Calls
TcpTransport::fromConnectedSocket($session->socket, $readTimeout)to wrap the live socket without re-runningstream_socket_client(). - Creates a fresh
ClientBuilderviaClientBuilder::create()and callssetTransport(...)on it with the transport from step 1. - Invokes the optional
$configureclosure with the builder as its only argument — this is the standard place to set security policy and mode, identity credentials, event dispatcher, logger, or to register extra modules. - Calls
$builder->connect($session->endpointUrl)and returns the resultingClient.
Inside Client::connect() the core's
ManagesConnectionTrait::performConnect() detects the
already-connected transport via transport->isConnected() and skips
the redundant transport->connect($host, $port) step. The HEL/ACK,
OPN, and CreateSession exchanges run identically to a regular client.
Configuring security and identity
use PhpOpcua\Client\ClientBuilder;
use PhpOpcua\Client\ExtReverseConnect\ReverseConnectClientFactory;
use PhpOpcua\Client\Security\SecurityMode;
use PhpOpcua\Client\Security\SecurityPolicy;
$client = (new ReverseConnectClientFactory())->buildClient(
$session,
static fn (ClientBuilder $b) => $b
->setSecurityPolicy(SecurityPolicy::Basic256Sha256)
->setSecurityMode(SecurityMode::SignAndEncrypt)
->setClientCertificate('/certs/client.pem', '/certs/client.key', '/certs/ca.pem')
->setUserCredentials('operator', 'secret'),
);
Do not override the transport in the closure
The factory has already wired a transport built from the inherited
socket. Calling $b->setTransport(new TcpTransport()) in the
$configure closure would discard that transport and force a brand
new outbound TCP connection on connect() — which defeats the whole
reverse-connect flow. Treat the transport as off-limits inside the
closure; configure everything else freely.
$readTimeout
Forwarded to TcpTransport::fromConnectedSocket(). When null, the
transport uses TcpTransport::DEFAULT_TIMEOUT (defined as 5.0
seconds at the time of writing — read the constant in
PhpOpcua\Client\Transport\TcpTransport for the authoritative
value).
Reconnection
A reverse-connected Client behaves like any other client returned
by ClientBuilder::connect(). If the channel drops and you call
reconnect(), the core attempts a regular outbound TCP connection
to $session->endpointUrl. If the server is unreachable from the
client side — which is often the whole reason you picked Reverse
Connect — that reconnect will fail, and the application must trigger
the server to dial back again.