-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathllms.txt
More file actions
154 lines (121 loc) · 11.2 KB
/
Copy pathllms.txt
File metadata and controls
154 lines (121 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# OPC UA Session Manager
> Daemon-based session manager for opcua-client. Keeps OPC UA connections alive across PHP requests via a ReactPHP daemon and a local IPC channel (Unix domain socket on Linux/macOS, TCP loopback on Windows — auto-selected). ManagedClient is a drop-in replacement for Client — same OpcUaClientInterface, persistent sessions.
## What is this
A PHP library that solves the OPC UA session persistence problem in PHP's request/response model. A long-running ReactPHP daemon holds OPC UA sessions in memory, and PHP applications communicate with it via a Unix socket. The connection handshake (50–200ms) is paid once; all subsequent requests reuse the existing session.
## Use cases
- Keep OPC UA sessions alive across HTTP requests in Laravel, Symfony, or plain PHP
- Avoid 50–200ms handshake overhead on every request
- Maintain subscriptions and monitored items between requests
- Run OPC UA operations from short-lived PHP-FPM workers
## Key features
- Drop-in replacement: ManagedClient implements the same OpcUaClientInterface as the direct Client
- Session persistence: OPC UA sessions survive across PHP requests via the daemon
- All OPC UA operations: browse, browseAll, browseRecursive, read, readMulti, write, writeMulti, call, subscriptions, history, path resolution, type discovery
- Human-readable NodeId strings: all methods accept 'i=2259' or 'ns=2;s=MyNode' in addition to NodeId objects
- Fluent Builder API: readMulti(), writeMulti(), createMonitoredItems(), translateBrowsePaths() support chainable builders when called without arguments
- Typed returns: all service responses return public readonly DTOs (SubscriptionResult, CallResult, BrowseResultSet, PublishResult, BrowsePathResult, MonitoredItemResult, TransferResult)
- Transfer & Recovery: transferSubscriptions() and republish() for session migration
- Type Discovery: discoverDataTypes() forwarded to daemon
- PSR-3 Logging: optional logger on ManagedClient
- PSR-16 Cache: invalidateCache() and flushCache() forwarded to daemon
- Security hardening: method whitelist (51 allowed operations), IPC auth token, credential stripping, error sanitization, connection limits
- Third-party module support (v4.2.0): any method registered on the daemon's client by a custom ServiceModule is callable via ManagedClient::$method(...). Args and results travel through a JSON wire codec (PhpOpcua\Client\Wire\WireTypeRegistry) with an explicit type allowlist — no unserialize() on the wire path, zero PHP gadget-chain surface
- Cross-platform IPC (v4.2.0): TransportInterface + AbstractStreamTransport (NDJSON framing, binary mode) + UnixSocketTransport (Linux/macOS default) + TcpLoopbackTransport (Windows default, loopback-only). TransportFactory auto-selects the right transport from an endpoint URI — unix:///path, tcp://127.0.0.1:port, or scheme-less path (= unix). Default per OS via TransportFactory::defaultEndpoint(). SocketConnection::send() delegates to TransportInterface. Daemon listener (React\Socket\SocketServer) accepts both unix:// and tcp:// URIs; construction-time loopback-only guard rejects any tcp:// bind to a non-loopback host on both client and daemon sides. ManagedClient works on Windows out of the box. WireMessageCodec handles typed envelope encoding with 16 MiB frame cap and 32-level depth cap
- Typed SessionConfig (v4.2.0): PhpOpcua\SessionManager\Daemon\SessionConfig readonly DTO with fromArray/toArray/sanitized() — CommandHandler::handleOpen() consumes typed fields instead of $config['...'] lookups; SESSION_CONFIG::SENSITIVE_FIELDS lists password/clientKeyPath/caCertPath/userKeyPath. Wire format unchanged for backwards compatibility
- Pluggable param deserializer (v4.2.0): ParamDeserializerInterface + ParamDeserializerRegistry + BuiltInParamDeserializer — the 200-line `match` previously embedded in CommandHandler is now a registry consulted first-match-wins. Third-party modules register their own deserializer via CommandHandler::registerParamDeserializer() without patching the command handler
- v4.5.0 alignment (lock-step with `opcua-client` v4.5.0, its security-hardening release): `PublishResult::$notifications` now holds typed `DataChangeNotification` / `EventNotification` objects instead of `['type' => 'DataChange', ...]` arrays — `TypeSerializer` serializes and rebuilds both, so `ManagedClient::publish()` returns real objects with decoded `DataValue` / `Variant` members; the IPC payload shape (`{type, clientHandle, dataValue|eventFields}`) is unchanged, so version skew works in both directions. New `ManagedClient::verifyApplicationUri(bool)` + `SessionConfig::$verifyApplicationUri` opt out of the core's new server-certificate to endpoint ApplicationUri binding (on by default). `EndpointDescription::$applicationUri` round-trips across IPC. Inherited for free on every daemon session: serverSignature verification, ECDH ephemeral-key signature verification, secure-channel header + anti-replay validation, SHA-256 trust-store content binding. No IPC protocol change
- v4.4.0 method surface (lock-step with `opcua-client` v4.4.0): 9 typed `historyInsert/Replace/Update/Delete*` methods (data and events), the `aggregate()` + `historyAggregate()` pair on `AggregateFunction` (Interpolate / Minimum / Maximum / Average / Count), and the OPC UA Part 5 `FileTransfer` surface — all reachable via `ManagedClient` over the existing `invoke` IPC command; no protocol change
- Auto-retry and auto-batching forwarded to daemon's Client
- Auto-publish: daemon automatically calls publish() for sessions with subscriptions, dispatching PSR-14 events (DataChangeReceived, EventNotificationReceived, AlarmActivated, etc.)
- Auto-connect: daemon connects and registers subscriptions at startup from pre-configured connection definitions
- Automatic cleanup: expired sessions closed after inactivity timeout
- Graceful shutdown: SIGTERM/SIGINT disconnect all sessions
## Architecture
- Client (src/Client/)
- ManagedClient (src/Client/ManagedClient.php): drop-in OpcUaClientInterface proxy, serializes calls to IPC
- SocketConnection (src/Client/SocketConnection.php): IPC client transport (delegates framing to Ipc\TransportInterface)
- Daemon (src/Daemon/)
- SessionManagerDaemon (src/Daemon/SessionManagerDaemon.php): ReactPHP daemon, event loop, cleanup timer, signal handlers, `VERSION` constant
- CommandHandler (src/Daemon/CommandHandler.php): IPC command dispatch, 51-method whitelist, security enforcement, auto-connect, `registerParamDeserializer()` extension point
- AutoPublisher (src/Daemon/AutoPublisher.php): per-session auto-publish cycle with self-rescheduling timers and ack management
- Session (src/Daemon/Session.php): session wrapper (Client + metadata + lastUsed + publishing intervals)
- SessionStore (src/Daemon/SessionStore.php): in-memory session registry with expiration
- SessionConfig (src/Daemon/SessionConfig.php): readonly DTO for `open` command payload (v4.2.0); `fromArray()` / `toArray()` / `sanitized()`; `SENSITIVE_FIELDS` constant covers password / clientKeyPath / caCertPath / userKeyPath
- Ipc (src/Ipc/, v4.2.0): cross-platform IPC primitives
- TransportInterface: contract for IPC transports
- AbstractStreamTransport: NDJSON framing on top of any stream
- UnixSocketTransport: Linux/macOS default (`unix:///path`)
- TcpLoopbackTransport: Windows default; rejects non-loopback hosts at construction
- TransportFactory: parses endpoint URI, returns matching transport; `defaultEndpoint()` picks per OS
- WireMessageCodec: typed envelope encoding/decoding (16 MiB frame cap, 32-level depth cap)
- Serialization (src/Serialization/)
- TypeSerializer (src/Serialization/TypeSerializer.php): bidirectional JSON serialization for all OPC UA types and DTOs
- ParamDeserializerInterface + ParamDeserializerRegistry + BuiltInParamDeserializer (v4.2.0): pluggable, first-match-wins decoder for IPC params; third-party modules register their own deserializer via `CommandHandler::registerParamDeserializer()`
- Cli (src/Cli/)
- ArgvParser (src/Cli/ArgvParser.php): parses `--socket`, `--timeout`, `--cleanup-interval`, `--auth-token`, `--auth-token-file`, `--max-sessions`, `--socket-mode`, `--allowed-cert-dirs`
- Logging (src/Logging/)
- StreamLogger (src/Logging/StreamLogger.php): minimal PSR-3 logger over a stream resource (used by `bin/opcua-session-manager` when no logger is injected)
- Exception (src/Exception/)
- DaemonException, SessionNotFoundException, SerializationException — typed errors raised from the IPC pipeline
## Installation
```
composer require php-opcua/opcua-session-manager
```
## Quick example
```php
use PhpOpcua\SessionManager\Client\ManagedClient;
// Start daemon first: php bin/opcua-session-manager
$client = new ManagedClient();
$client->connect('opc.tcp://localhost:4840');
$value = $client->read('i=2259');
echo $value->getValue();
$refs = $client->browse('i=85');
foreach ($refs as $ref) {
echo "{$ref->displayName} ({$ref->nodeId})\n";
}
$client->disconnect();
```
## Session persistence
```php
// Request 1: open session (handshake happens once)
$client = new ManagedClient();
$client->connect('opc.tcp://localhost:4840');
$sessionId = $client->getSessionId();
// Store $sessionId — do NOT disconnect
// Request 2: session is still alive in daemon
$client = new ManagedClient();
$client->connect('opc.tcp://localhost:4840');
$value = $client->read('i=2259'); // ~5ms instead of ~155ms
```
## Daemon options
--socket, --timeout, --cleanup-interval, --auth-token, --auth-token-file, --max-sessions, --socket-mode, --allowed-cert-dirs
## Main classes
- PhpOpcua\SessionManager\Client\ManagedClient — drop-in OpcUaClientInterface proxy
- PhpOpcua\SessionManager\Client\SocketConnection — Unix socket JSON transport
- PhpOpcua\SessionManager\Daemon\SessionManagerDaemon — ReactPHP daemon
- PhpOpcua\SessionManager\Daemon\CommandHandler — IPC command dispatch and security
- PhpOpcua\SessionManager\Daemon\AutoPublisher — per-session auto-publish cycle manager
- PhpOpcua\SessionManager\Daemon\Session — session wrapper
- PhpOpcua\SessionManager\Daemon\SessionStore — in-memory session registry
- PhpOpcua\SessionManager\Serialization\TypeSerializer — JSON ↔ OPC UA type conversion
- PhpOpcua\SessionManager\Exception\DaemonException — daemon communication errors
- PhpOpcua\SessionManager\Exception\SessionNotFoundException — session not found
- PhpOpcua\SessionManager\Exception\SerializationException — type serialization errors
## Related packages
- php-opcua/opcua-client: core OPC UA client library (required dependency)
- php-opcua/laravel-opcua: Laravel integration (service provider, facade, config)
- php-opcua/opcua-cli: CLI tool for OPC UA operations
- php-opcua/opcua-client-nodeset: Pre-generated PHP types from OPC Foundation companion specifications
- php-opcua/uanetstandard-test-suite: Docker-based OPC UA test servers (UA-.NETStandard)
## Requirements
- PHP >= 8.2
- ext-openssl
- ext-pcntl (recommended)
- php-opcua/opcua-client ^4.5
## License
MIT
## Links
- Repository: https://github.com/php-opcua/opcua-session-manager
- Documentation: https://github.com/php-opcua/opcua-session-manager/tree/master/docs (or https://www.php-opcua.com/documentation/opcua-session-manager)
- Issues: https://github.com/php-opcua/opcua-session-manager/issues
- Packagist: https://packagist.org/packages/php-opcua/opcua-session-manager