feat(opcuaclient): #676 follow-ups — endpoint rewrite, stall wire test, fast definitive-loss recovery
- Endpoint rewrite: the driver now connects to the configured host AND port (scheme match, advertised path kept) instead of the server-advertised URL — fixes NAT/port-map upstreams and lets an in-test proxy carry the session (SDK SelectEndpoint rule). - TcpStallProxy + OpcUaClientDriverStallWireTests: the in-place blip (#670) is now wire-tested on loopback — one Bad, frozen read stamp, same session, identical value republished Good, a post-recovery change arrives, no source-time regression after the SDK's late backlog flush. - Defect found by that test, fixed: a change published right after a stall rode a Publish response the SDK timed out and never republished, leaving the node Good on the pre-change value indefinitely. New trailing reconcile read (Timeout + KeepAliveInterval after recovery) publishes any Good value newer than the last accepted one, through the replay guard's mark. - IDriverConnectionLossSource (Core.Abstractions): opt-in definitive-loss signal. DriverInstanceActor attaches in PreStart / detaches in PostStop and turns a raise into a disconnect only while Connected. OpcUaClient raises once per session on keep-alive BadSessionIdInvalid/BadSessionClosed/BadSessionNotActivated/ BadServerHalted (measured: the SDK never re-opens a halted channel) or a dropped subscription; ambiguous codes stay with the #527 watchdog. - Replay guard: one Information summary per recovery when the window closes ("dropped N late notifications across M refs"), with a timer so quiet subscriptions log it too. - ReconnectPeriod deleted (options, AdminUI form, docs, tests); stored configs that carry reconnectPeriod still parse in the factory, probe and browser. - Docs: OpcUaClient.md, DriverLifecycle.md, driver-specs.md, CLAUDE.md.
This commit is contained in:
-4
@@ -34,7 +34,6 @@ public sealed class OpcUaClientDriverPageFormSerializationTests
|
||||
Timeout = TimeSpan.FromSeconds(20),
|
||||
SessionTimeout = TimeSpan.FromSeconds(180),
|
||||
KeepAliveInterval = TimeSpan.FromSeconds(10),
|
||||
ReconnectPeriod = TimeSpan.FromSeconds(15),
|
||||
AutoAcceptCertificates = true,
|
||||
BrowseRoot = "i=85",
|
||||
MaxDiscoveredNodes = 5000,
|
||||
@@ -58,7 +57,6 @@ public sealed class OpcUaClientDriverPageFormSerializationTests
|
||||
back.Timeout.ShouldBe(TimeSpan.FromSeconds(20));
|
||||
back.SessionTimeout.ShouldBe(TimeSpan.FromSeconds(180));
|
||||
back.KeepAliveInterval.ShouldBe(TimeSpan.FromSeconds(10));
|
||||
back.ReconnectPeriod.ShouldBe(TimeSpan.FromSeconds(15));
|
||||
back.AutoAcceptCertificates.ShouldBeTrue();
|
||||
back.BrowseRoot.ShouldBe("i=85");
|
||||
back.MaxDiscoveredNodes.ShouldBe(5000);
|
||||
@@ -105,7 +103,6 @@ public sealed class OpcUaClientDriverPageFormSerializationTests
|
||||
Timeout = TimeSpan.FromSeconds(12),
|
||||
SessionTimeout = TimeSpan.FromSeconds(150),
|
||||
KeepAliveInterval = TimeSpan.FromSeconds(7),
|
||||
ReconnectPeriod = TimeSpan.FromSeconds(8),
|
||||
AutoAcceptCertificates = true,
|
||||
BrowseRoot = "i=85",
|
||||
MaxDiscoveredNodes = 3000,
|
||||
@@ -133,7 +130,6 @@ public sealed class OpcUaClientDriverPageFormSerializationTests
|
||||
result.Timeout.ShouldBe(TimeSpan.FromSeconds(12));
|
||||
result.SessionTimeout.ShouldBe(TimeSpan.FromSeconds(150));
|
||||
result.KeepAliveInterval.ShouldBe(TimeSpan.FromSeconds(7));
|
||||
result.ReconnectPeriod.ShouldBe(TimeSpan.FromSeconds(8));
|
||||
result.AutoAcceptCertificates.ShouldBeTrue();
|
||||
result.BrowseRoot.ShouldBe("i=85");
|
||||
result.MaxDiscoveredNodes.ShouldBe(3000);
|
||||
|
||||
Reference in New Issue
Block a user