- Move all channel-related types into `Stack/Opc.Ua.Core/Stack/Client/Channels/`
subfolder (#13).
- Un-obsolete `SessionReconnectHandler` and the SessionExtensions
`ReconnectAsync(connection, ct)` / `(channel, ct)` extensions; remove
all SRH-related `#pragma warning disable CS0618` suppressions from
applications and tests. AttachChannel/DetachChannel remain obsolete (#1, #4).
- Remove the shared-budget section from MigrationGuide.md (#3).
- Mark `ManagedSession.AttachChannel`/`DetachChannel` `[Obsolete]` so the
warning surfaces all the way up the supported API surface (#9).
- Break the `<see cref=…>` line in `Session.ChannelManager.cs` to stay under
140 chars (#10).
- Move `ChannelManagerSessionFactory` from `Opc.Ua.Gds.Client.Common` into
`Opc.Ua.Client` as a public, documented session-factory option (#11).
- Audit other client classes for `IClientChannelManager`-aware overloads;
add `ISessionFactory`-accepting overloads on `GlobalDiscoveryServerClient`,
`LocalDiscoveryServerClient`, `ServerPushConfigurationClient` so any
session factory (including `ChannelManagerSessionFactory`) works (#12).
- Refactor MCP server (`OpcUaSessionManager`, `Program`) to use
`ManagedSession` + DI-resolved `IClientChannelManager`; remove
`SessionReconnectHandler` and manual keep-alive reconnect (#2).
- ConnectionStateMachine code-style fixes: use named delegate types,
collapse multi-line callback properties to single lines, swap
`timeProvider`/`maxTotalReconnectTime` constructor param order,
fix multi-line declaration (#6, #7, #8).
- HTTPS resilience: confirmed `Microsoft.Extensions.Http` and
`Microsoft.Extensions.Http.Resilience` 10.6.0 support
`net472`/`net48`/`netstandard2.1`; removed `#if NET8_0_OR_GREATER`
gating from `ManagedSessionBuilder` and `OpcUaClientBuilderExtensions`
and HTTPS csproj package refs (#5).
Verification:
- `Opc.Ua.Client` + `Opc.Ua.Core` + `Opc.Ua.Gds.Client.Common` build
clean (0 warnings, 0 errors).
- 56/56 core channel-manager / retry-budget / HTTPS factory tests pass.
- 129/129 client (ManagedSession + legacy SRH back-compat + SessionExtensions)
tests pass.
Introduces `IClientChannelManager` as the central registry for client-side
transport channels. Sessions and discovery clients now share ref-counted
managed channels per (endpoint, reverse-connect identity); reconnect is
coalesced and notified to attached participants via a new
`IReconnectParticipant` callback interface; service calls are gated by a
three-state lifecycle (`TransportReconnecting` -> `TransportConnectedSessionReactivating`
-> `Ready`) until reactivation completes.
New types in `Stack/Opc.Ua.Core/Stack/Client/`:
- `ManagedChannelKey`, `ChannelState`, `ChannelStateChange`, `ParticipantReconnectResult`
- `IReconnectParticipant`, `IManagedTransportChannel`, `IClientChannelManager`
- `IChannelReconnectPolicy` + `ExponentialBackoffChannelReconnectPolicy`
- `IRetryBudget` + `RetryBudget` (shared retry deadline across the two layers)
- `ClientChannelManager.Managed/Entry/Lease/Metrics/Diagnostics/CertRotation.cs`
partials with refcount, coalesced reconnect, IMeter instruments, ActivitySource
+ EventSource, and automatic ReconnectAllAsync on certificate rotation.
Session integration (Libraries/Opc.Ua.Client):
- `Session.CreateAsync(IClientChannelManager, ...)` overload constructs a
Session that shares its channel with co-located participants.
- `Session` implements `IReconnectParticipant`; reactivation handler
distinguishes Reactivated / RequiresSessionRecreate / TransientFailure /
FatalForParticipant / FatalForChannel.
- `Session.ReconnectAsync(ct)` automatically delegates to the channel
manager when wired.
- `Session.RecreateInPlaceAsync` swaps managed-channel leases for
failover-to-different-endpoint; same-key recreates delegate to manager
reconnect; explicit channel/connection callers retain legacy behavior.
- KA failure routes through `IClientChannelManager.ReconnectAsync(channel)`.
ManagedSession integration:
- `WithChannelManager(...)` builder + ctor param.
- Two-level retry: channel-mgr handles transparent reconnect; outer
`ConnectionStateMachine` + `IReconnectPolicy` only triggers on terminal
channel `Faulted`. Outer-state churn suppressed during channel-mgr
cycles via `_channelReconnectInProgress` flag wired through
`IManagedTransportChannel.StateChanged`.
- New `ManagedSession.ChannelStateChanged` event surfaces transparent
reconnects to UI / health dashboards.
- `ConnectionStateChangedEventArgs.UnderlyingChannelState` populated when
outer reconnect was triggered by a channel fault.
- Shared `IRetryBudget` propagated to channel-mgr so the two layers
enforce a single max-total-time instead of compounding multiplicatively.
Discovery/Registration/GDS:
- Channel-manager-aware `CreateAsync` overloads on `DiscoveryClient`,
`RegistrationClient`, `ServerPushConfigurationClient`,
`LocalDiscoveryServerClient`, `GlobalDiscoveryServerClient`. Each
registers a minimal `IReconnectParticipant`; co-located sessions and
discovery probes targeting the same endpoint share a channel.
HTTPS transport (`Stack/Opc.Ua.Bindings.Https/`):
- New `IOpcUaHttpClientFactory` abstraction.
- HTTPS / OPC-HTTPS channels migrated to `IHttpClientFactory` +
`Microsoft.Extensions.Http.Resilience` (10.6.0, AOT-compatible on net10
via source generators; legacy direct-HTTP path retained for older TFMs
/ no-DI consumers).
DI:
- `AddOpcUa().AddClient(...)` registers `IClientChannelManager` and the
named HTTPS HttpClient + standard resilience handler automatically.
- `ManagedSessionBuilder` resolves the manager from DI when present.
Obsoletions (functional, `[Obsolete]` with guidance):
- `IClientBase.AttachChannel`/`DetachChannel`
- `SessionReconnectHandler`
- `SessionExtensions.ReconnectAsync(connection, ct)` and `(channel, ct)`
legacy overloads
Tests (~70 new unit + 4 live-server integration fixtures):
- Core: `ClientChannelManagerManagedTests`, `ClientChannelManagerCertRotationTests`,
`RetryBudgetTests`, `OpcUaHttpClientFactoryTests` (56/56 pass).
- Client: `ManagedSession*Tests` updated (129/129 pass) + back-compat
suites pass with `#pragma warning disable CS0618`.
- Sessions integration: `ChannelManagerSharing/TransparentReconnect/SessionLifecycle/CertRotation`
(6 pass, 2 skipped with documented blockers for faulted-entry reset and
RequiresSessionRecreate end-to-end plumbing).
Builds clean (0 warnings / 0 errors) across all six TFMs (net472, net48,
netstandard2.1, net8.0, net9.0, net10.0).
Docs:
- `Docs/Sessions.md` new section 4 documents the channel manager,
three-state gating, two-level retry with shared `IRetryBudget`, and
HTTPS resilience layering.
- `Docs/MigrationGuide.md` migration recipes for the four obsoleted API
groups.
- `Docs/DependencyInjection.md` channel-manager and HTTPS factory
registration.
- Add new managed session, wrapping session and providing connection management and failover handling
- Add new Subscription engine that can act as alternative to current engine, but is based on channels with worker tasks
- Add a fluent builder for managed session clients
- Replace NodeCache with LruNodeCache, rename ILruNodeCache and LruNodeCache to INodeCache and NodeCache
- Update migration guide and document new functionality.
Generate stack and application code using source generators
Change built in types to readonly structs
Update localized text implementation to use JSON text serializer
Status code with symbolic names
Immutable node ids
No boxing for all built in types <= 8 bytes in Variant.
Split user identity token and token handling via token handler
Add migration guide for breaking changes