# Description Extract shared stack, regression-test, sample and documentation changes from draft #4462 into a separate prerequisite PR. The PR now contains **19 shared paths**: the original eighteen extracted files plus a focused user-management regression file added during review. It does not include UaLens source, desktop dependencies, solution registrations or application documentation. ## Changes - Correct the V2 ConditionRefresh target and response validation. Bound disposal-time remote subscription deletion with an independent five-second TimeProvider-backed cancellation deadline, allowing local cleanup after a server outage. This is a per-delete limit, not a global application shutdown deadline. - Preserve configured PubSub writer message/header settings, canonical numeric JSON publisher matching, and flattened DataValue quality/timestamps. - Add asynchronous user-management client wrappers over the generated standard proxy, and set file/directory method declaration IDs needed by typed client workflows. - Enable AI client NativeAOT compatibility and add focused AI client regressions. - Enable the ConsoleReferenceServer file-system node manager and configure 1 ms publishing/sampling demonstrations. These sample defaults do not promise hard real-time delivery. - Document the subscription and PubSub behavior. Make the new subscription/PubSub regression helpers portable to .NET Framework without weakening their assertions. ## Review follow-up Commit `812297ce1` aligns both public `ListUsersAsync` signatures with `ValueTask<ArrayOf<UserManagementUser>>`. The implementation constructs its result directly from an owned snapshot array, without an intermediate list. Five focused cases pass on **net10.0 and net48**: `ListUsersReturnsArrayOfSnapshotsAsync` checks both interface and concrete entry points and preserves snapshot order, values and flags; `ListUsersReturnsEmptyArrayAsync` covers typed-empty and missing values; `ListUsersPreservesBadReadStatusAsync` checks the exact server failure status. All **eight single-line XML summaries** were converted to multi-line form. A complete scan of the fourteen changed C# files, including the new test, finds zero remaining single-line summaries. Scoped whitespace/line-ending verification passes. The sole UaLens caller was adapted separately in draft #4462 (`4caf69f33`). A fresh combined dependency-graph build and all **924 UaLens net10.0 tests** pass with both changes. Each of the three review threads received an action-taken reply and was resolved only after the fixes were pushed and verified. ## Split boundary The branch originated at `a45105375`; the subsequent master merge `f209f3804` incorporates upstream `4633aa7a3`. The original shared changes and review regression remain separate from the app. Draft #4462 retains `tools\Opc.Ua.Lens`, `tests\Opc.Ua.Lens.Tests`, and its six solution/package/documentation integration files. **Merge this prerequisite before the UaLens draft.** The draft consumes the extracted APIs. Published history is preserved; neither PR has been merged automatically. ## Initial split validation The following results describe the initial split validation at `fa7199afa`; current review-specific validation is recorded above. | Scope | net10.0 | net48 | |---|---:|---:| | Client subscription/file-system tests | 168 passed | 168 passed | | Server file-system/user-management tests | 244 passed | 244 passed | | PubSub writer/reader regressions | 34 passed | 34 passed | | ConsoleReferenceServer build | Passed | Passed | The corrected portable regression helpers were rechecked on net10.0 after the net48 fixes. The combined UaLens application also passed its 924-case net10.0 suite before extraction. **Focused NativeAOT: 16 passed, zero failed/skipped.** A session-local TUnit runner linked the exact committed `AIClientAotTests.cs` and referenced the real AI client project. It published without warnings or suppressions and executed as a genuine Windows native binary with no CLR header. The canonical `Opc.Ua.Aot.Tests` project was blocked by pre-existing CS8632 nullable-annotation errors in unchanged upstream `SchemaAotTests.cs` (lines 82, 127, 129 and 132). Its existing nullable configuration and all upstream tests were preserved; the focused result is not a claim that the full AOT test project builds. The net48 hosting selection uses a short NUnit WorkDirectory: the existing fixture builds long PKI paths that otherwise exceed the platform's path limit. The original full selection passed without test exclusions, source changes or increased timeouts. Scoped builds reported inherited warnings in unchanged upstream files: CA1508 in `ReferenceBuilderExtensions.cs`, CA1861 in `NodeSetImportIntegrationTests.cs`, and net48 CA1823 in `DefaultNodeIdFactory.cs`. They were not suppressed or folded into this split. Full-solution, coverage and CI/CodeQL gates remain unasserted. ## Related Issues - Tracking/design review: #4461. - Prerequisite extracted from draft #4462. ## Checklist - [ ] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [ ] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [ ] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [x] I have addressed **all** PR feedback received. Tests and scoped results are documented above; measured coverage, inherited-warning qualification, CLA status, full-solution results and CI completion are not asserted by these checkboxes. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.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.