Shortens CTT runs against the reference server without changing what the CTT verifies. ## Changes - **Alarm simulation step in `--ctt` mode: 1000 → 500 ms.** `AlarmNodeManagerFactory.SimulationInterval` (default stays 1000 ms) is passed to `AlarmNodeManager`; `ConsoleReferenceServer --ctt` sets it via `Quickstarts.Servers.Utils.ConfigureCttModeNodeManagers()` to `Utils.CttAlarmSimulationInterval` (500 ms) before the node managers are created. A full alarm cycle (40 steps through all limits) takes 20 s instead of 40 s. Every alarm still passes through all states and limits; the alarm NodeIds carry the interval (`…ExclusiveLevelAlarmType.500.Alarm` in CTT mode). - **`Ctt.ReferenceServer.Config.xml`: `MinSubscriptionLifetime` 10000 → 1000 ms.** CTT scripts request short subscription lifetimes on purpose and then wait for them to expire (Subscription Basic 063/016, Durable 012, Minimum 02 004, Publish Min 05 Err-001, Diagnostics 024); the 10 s floor inflated those waits. Part 4 sets no minimum; the server still enforces lifetime ≥ 3 × keep-alive. ## Measured (patched CTT 1.05.513 scripts) | Part | Before | After | | --- | ---: | ---: | | A&C (p18), alarm step only + CTT Alarm Cycle Time 20 | 932 s | 576 s | | Subscriptions (p16), MinSubscriptionLifetime only | 679 s | 579 s | Combined full run with the matching CTT-side changes (ReadyToRun server build, publish interval 150 ms, SecureChannel min lifetime 1000 ms, A&C Refresh script waits): **72 → 54 min**, 0 regressions against the CTT baseline (the only error is the known CTT-binary defect GDS 019). The CTT CI repo derives its `Alarm Cycle Time` from `Utils.CttAlarmSimulationInterval`, so runs against branches without this change keep the old 30 s setting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
OPC Foundation UA .NET Standard Reference Server
Introduction
The console reference server can be configured using several console parameters. Some of these parameters are explained in more detail below.
To see all available parameters call console reference server with the parameter -h.
Historical Access
The reference server starts with an in-memory Part 11 historian. Its historized
scalar nodes expose raw, modified, at-time, aggregate, annotation, and update
operations together with populated HistoricalDataConfigurationType
companions. CTT/Historical_KeyValuePairs demonstrates generic
StructuredHistoryData with two KeyValuePair entries at one timestamp. The
CTT notifier exposes historical event read/write bits, a
HistoricalEventConfigurationType companion, and seeded event history.
Writes to the two event-trigger variables report events; live forwarding
completes before the historian snapshots them into its bounded asynchronous
capture queue.
Run the matching client workflow with:
dotnet ConsoleReferenceClient.dll --historian --autoaccept --nosecurity \
opc.tcp://localhost:62541/Quickstarts/ReferenceServer
See docs/HistoricalAccess.md for the
provider contracts, status semantics, and custom storage examples.
Reverse Connect
The OPC UA reverse connect feature allows an OPC UA server to initiate the connection to a client, rather than the traditional model where clients connect to servers. This is particularly useful in scenarios where the server is behind a firewall or NAT, making it difficult for clients to directly connect to it.
How to use Reverse Connect
To enable reverse connect mode, specify the client endpoint URL using the --rc or --reverseconnect parameter:
dotnet ConsoleReferenceServer.dll --rc=opc.tcp://localhost:65300
or
dotnet ConsoleReferenceServer.dll --reverseconnect=opc.tcp://localhost:65300
Example: Server and Client with Reverse Connect
-
Start the client with reverse connect listener on port 65300:
dotnet ConsoleReferenceClient.dll --rc=opc.tcp://localhost:65300 opc.tcp://localhost:62541/Quickstarts/ReferenceServer -
In a separate terminal, start the server with reverse connect to the client:
dotnet ConsoleReferenceServer.dll --rc=opc.tcp://localhost:65300 -a
The server will establish a reverse connection to the client endpoint, and the client will use this connection to communicate with the server.
Additional Options
-aor--autoaccept: Auto accept untrusted certificates (for testing only)-cor--console: Log to console-lor--log: Log app output-tor--timeout: Timeout in seconds to exit application
For the complete list of options, use --help.
X509 user identity certificates
The reference server validates X509 user identity tokens against its trusted-user certificate
store (TrustedUserCertificates, by default %LocalApplicationData%/OPC Foundation/pki/trustedUser).
An untrusted user certificate is rejected with BadIdentityTokenRejected — the --autoaccept option
only auto-accepts the application/channel certificate, never user identity certificates.
To let a trusted client (for example the OPC Foundation Compliance Test Tool) authenticate with an
X509 user token, its user certificate must be present in that store. To make provisioning easy, the
server writes every rejected X509 user certificate to a dedicated review store,
pki/rejectedUser (a sibling of pki/trustedUser). After one failing activation you can move the
legitimate user certificate from pki/rejectedUser/certs into pki/trustedUser/certs (and any
issuing CA into pki/issuerUser/certs) and reconnect. Deliberately-untrusted certificates simply stay
out of the trusted store and continue to be rejected.