Fix cases where a cancellable WaitAsync(ct) on a SemaphoreSlim within a try/finally could end up in a deadlock.
Fix: The WaitAsync must be outside the try/finally block. if the WaitAsync is cancelled, it should not release the semaphore
- Implement the reconnect and republish with async service calls.
bug fixes:
- subscription Ids should start from a random number
- the keep alive interval calculation is too short, adding +1 for the timeout
- on BadSessionIdInvalid recreate session immediately
- on a restarted server with new certificate, also reload endpoints when BadCertificateInvalid is returned
Currently, due to some internal cloning of sessions, subscriptions and monitored items it is not possible to use subclassed variants which are properly recreated after a session reconnect.
- Add a `ISessionInstantiator` interface to allow to subclass a `Session` and override virtual function.
- Add a `Subscription.CloneSubscription` and `MonitoredItem.CloneMonitoredItem` virtual method to recreate those with event handlers and client handles.
- A sample implementation with `TestableXXX` classes is provided to test the BadInvalidTimestamp fix by injecting modified timestamps in the session class.
- Remove duplicate `IDisposable` with `Session`. `IClientBase` is disposable already.
- adds `knownTypes` parameter to `Session.Load` and `Session.Save` to support save and restore of custom Subscriptions and Monitored items.
bug fixes:
- IOP: an empty DataTypeDictionary throws an exception when loaded by the complex type system, server are allowed to leave it empty to save memory.
- BadInvalidTimestamp should not be returned when the timestamp in the requestheader is out of sync. #2364
- CloseAsync still used the 'Close' synchronous function
- remove a duplicate definition of IDisposable on ISession
- reduce the log output when the server publish time is out of sync
- improve various log messages, comments etc.
- multiple internal improvements in naming convention handling of async functions
- add FetchSuperTypesAsync
- replace new UTFEncoding() with Encoding.UTF8 singleton
- Improvements when many sessions need to be opened
- Introduce a OpenAsync version which usesmore async calls for session creation
- add async interfaces to cert validator
- refactor lock of encodeable factory
- add a `EndAsync` property to WriteRequest to allow to await a service call
- add a `EndSendRequestAsync` method to allow implementation of awaitable service calls
Issues:
- The expectation is for a client session to receive a `GoodSubscriptionTransferred` status after a subscription is transferred to another session. However there is a corner case exposed in our tests, when all subscriptions are transferred so that the client subscriptiona has no active subscriptions left, only `BadNoSubscription` is returned by the server for allpending requests, instead of the status. As a workaround, to get the status, the client session has to send an additional publish request which is unexpected after a `BadNoSubscription` error.
- The status message is only returned on the next publish request, which can lead to undesired delay of the notification.
Fix: Return the status message immediately if pending requests are available.
Other fixes:
- Make client subscription class cloneable
- Improve the test which didn't receive the status messages
- Use the publish request queue to return a status message immediately
- Add the event `SessionConfigurationChanged` which indicates that the `SaveSessionConfiguration` should be called again because some session configuration was changed, e.g. after a reconnect, locale, server nonce or the user impersonation changed.
* Fixed status code when server is shutdown
* Add latest statuscodes from 1.05.03 to support new BadServerTooBusy error code
* added default throttle delay in case an unknown error is returned on a publish request service call
- A few use cases were still missing from the ISessionFactory interface to make the static `Session.Create` functions completely obsolete.
- Follow naming conventions (Async) and add CancellationToken where missing.
- Add the system diagnostics library for unsupported target platforms
- Integrate in clientfixture by adding IDisposable to support to enable/disable the activity tracing
- fix Traceable session dispose issue, do not null the disposed session
- Add traceable client session with factory to support ActivitySource on .NET 6
- Only traces the public API calls, inner calls are not yet supported.
- Uses the name: Opc.Ua.Client-TraceableSession-ActivitySource
- shutdown the worker tasks with a ManualResetEvent instead of timer null check
- Breaking change: Decorate the PublishStateChanged event handler with state information:
- - Stopped/Recovered if publish times out/restarts
- Breaking change: PublishStateChange fired for every received publish response, which doesn`t really indicate a state change.
-- new behavior: fires only if a Keep alive or republish is triggered.
- Support Client.Session API to save and restore session configuration information as xml or in a serializable data structure.
- Support to reactivate a session using a new secure channel.
- API tests
- `DiagnosticInfo` contains the `InnerDiagnosticInfo` which can be nested. Limit the recursion to `MaxInnerDepth` in multiple places to prevent stack overflow / endless loops.
- The default value for MaxInnerDepth should not be more than 5.
- With the `sequentialPublishing` flag enabled, no data is received after transfer. Fix: add a resync flag to update the last sequence counter after transfer.
- Instead of the semaphore slim use a dedicated Task per subscription. The task is using `AsyncAutoResetEvent` to be task friendly, becasue every subscription gets a worker task.
- Add more tests for the use case republish with delayed ack.
- Add a test and a missing method to support reconnect of a session on a different secure channel without reconnect handler.
- Issue fix: Currently when diagnostics is enabled in client calls, the string table in the response header is not updated when a service call is split into multiple service calls. In this case the stringtables from all calls must be appended and the index in the diagnosticinfo must be updated to match the updated string list.
- To reduce the number of 'null' DiagnosticInfo allocations, the decoders now try to return null instead of a default DiagnosticInfo. A new property ÌsNullDiagnosticInfo' can be used to check for unused DiagnosticInfo entries.
- The tests were slightly improved to use test set data from the generated TestData namespace, which contains also a historical node.
- All `ServerFixtureUtils.ValidateXXX` checks were updated to include the check for diagnosticInfos and the string tables to catch issues.
- SessionClientBatched doesn't handle the case when diagnosticinfos are requested and the batched calls returns mixed empty or non empty diagnostic infos, then the returned infos did not match the number of requested items.
- write of arrays of analogItemState are not properly checked
- BuildInfo properties were empty because BuildInfoVariableValue is never initialized
- DataType and ReferenceType may return null attributes instead of BadAttributeIdInvalid.
- Add BuildInfo test and fix the NodeCacheTest
- With exponential backoff enabled, a KeepAlive calling `BeginReconnect` could retrigger the timer in a way that a reconnect would never occur.
- Throttle `ISession.BeginPublish` on `BadTooManyOperations` error.
- Add reverse connect option to console client to test reconnect with reverse connect manager.
- null events in session on dispose to suppress spurious events.
- mark `TransferSubscription` service calls obsolete to avoid accidential use by applications.
- for reverse connection testing of session reconnect handler, add options for no security and reverse connect endpoint to console client
- if `DisableMonitoredItemCache` is set, the sequencenumber and publish time are unavailable. Add helpers to NotificationData to get the information in the fast data and event callbacks.
- new fast callback for keep alive messages
Starting with line 1857 a dictionary of namespaces is populated in an defensive manner. If a namespace value can't be read, it is silently ignored. If this happens, it will result in an KeyNotFoundException when populating the imports dictionary.
This fix adds a warning if a namespace value can't be read and populates the imports dictionary also defensivly.
- Deprecate support for Nuget package support of .NET Framework 4.6.2
- Bump sample applications to 4.8
- update some copyright headers / supporting files (editorconfig etc.)
- fix a few warnings
- fix an issue with `SessionReconnectHandler`, in certain combination of reconnect period and exponential backoff the .NET sample app never reconnected.
- due to the new `MinPublishRequestCount` property publish requests are being sent after reconnect even if no subscription is active
- Improve sample code to show how to dispose the old session after reconnect
Currently the session reconnect requires to create and destroy the object and to lock the operation in the client code.
The refactored version is backward compatible but allows for a single instance to handle reconnects during the lifetime of the client. In addition no more locking is necessary in the client code.
- exponential backoff is enabled by using a constructor `new SessionReconnectHandler( true, 30000);` which would set the maxReconnectPeriod` to 30000ms. The backoff period is doubled after every unsuccessful request.
- a 10% random jitter is added to every timer update.
- The `public virtual int JitteredReconnectPeriod(int reconnectPeriod)` and `public virtual int CheckedReconnectPeriod(int reconnectPeriod, bool exponentialBackoff = false)` can be overloaded to implement custom jitter and backoff implementations.
- A new `ISession.MinPublishRequestCount` property can be set to enforce a minimum number of active publish requests. Default behavior is one publish request per subscription. It can help for low latency high frequency publish intervals.
- A new `PublishSequenceNumbersToAcknoledge` event is implemented which allows to defer ack of sequence numbers until fully processed by the client.
All new methods/properties ar not breaking changes and by default there is no behavior change, all existing code should work and compile aginst the update flawlessly.
- A bugfix in the reconnect handler, when a server changed the application certificate the reconnect ends up in an endless loop, because the `EndpointDescription` is not updated. The fix updates the endpoint from the server if a `BadSecurityChecksFailed` error os returned and then tries to reconnect with a new session.
- ICloneable was removed from generated code for the first port to .NET Standard 1.x, instead MemberwiseClone was used
- Reenable ICloneable for generated code
- Add ICloneable to built in types
- Fix code where MemberwiseClone is called instead of Clone
- Added a flag to the Session.Load function to indicate that a session transfer should be supported. Otherwise the serverId is reset after load, to support that the subscription is recreated on the server after load.
- A user has to opt-in to get the transfer session support.
* INodeCache lacks an interface to directly call `IList<INode> Find(IList<ExpandedNodeId> nodeIds);`
* Handle a special case where a `BadNothingToDo` error would disrupt the Fetch for NodeCache.
-Currently the server startup tries to load bindings for all known schemes, even if no baseaddress was specified.
Filter the required schemes to load only if necessary.
-Make GetDiscoveryUrl helper public
-Add Session.CloseAsync methods.
-Add missing Close signatures to ISession
-Mark the CloseSession service call as obsolete to prevent invalid usage
-fix UANodeSetHelper.Save(stream), to not close the stream
-fix a deadlock in the ref server app, due to the new default behavior of the cert validator not caching the approved certificates
Expose an 'ISession' interface as abstraction to ease unit testing.
Breaking changes are kept to minimal impact, but some changes maybe required to use ISession objects instead of Session.
Note: ISessionClientMethods is hand created, not yet by ModelCompiler
Improvements for complex types.
- Support to encode/decode complex type structures with multidimensional arrays.
- Perf improvements for type loader using new NodeCache fetch multiple interfaces.
- DataTypeDictionary validation when dependencies are used.
- interface for complex type resolver, to build custom types in code.
- improvements of console client to demonstrate browse/read of custom values
+++ Breaking changes +++
IDecoder interface change of the `ReadArray` method
- Return type is now `Array` for all types of arrays. Previously the method returned an array for 1-dim and a `Matrix` type for multidimensional arrays. In addition the convention in generated code is to use `Collection` for all 1-dim arrays, and so was built the `BaseComplexType`. The new convention is to expose the native `Array` type from a complex type, in all cases, hence the return type of `ReadArray` was changed to reflect that for a consistent programming model.
- `ReadArray` has a new parameter `systemType` to efficiently read encodeable types. Previously the `Type` of an encodeable was determined by the encodingid and lookup in the type factory, even when the Type is already known by the caller. The 'old' style is still supported.
- `ReadArray` supports to read encodeable type arrays which are directly encoded in structures. These arrays differ from standard encoding of arrays and they are handled when `BuiltInType.Null` is used as parameter.
-Make the https callbacks fully async / code cleanup.
-Default https client to use MaxConnectionsToServer = 64 for #1550
-Fix https missing reconnect error code
other fixes unrelated to https:
- move trust list audit event to AuditEvents.cs, fix issue that the event is not filtered since reportAuditEvent cannot be used
- fix an issue when BrowseNext for multiple continuation tokens doesn't add the results array properly
- bump up .NET Core 3.1 Nuget dependencies
- improve .NET reference client app for use with https
- Add methods to support to Read/Browse multiple nodes in session and NodeCache.
- Add methods to find references of multiple nodes in NodeCache.
- By default the client fetches the operation limits from the server.
- Add operation limit object to client config, settings are overwritten by server limits if server limits are smaller.
- Split client service calls if operation limits are exceeded with an override of the SessionClient. All sync/async service calls are implemented, but not the servcie calls using the Begin/End pattern.
* Add new methods for reading a set of nodes
* ReadNodes(NodeIdCollection, out DataValueCollection, out IList<ServiceResult>, bool optionalAttributes)
* (DataValueCollection, IList<ServiceResult>) ReadNodesAsync (NodeIdCollection, bool optionalAttributes)
to reduce the amount of attributes read from a server ReadNodes first reads only the NodeClass, then reads only the mandatory attributes per nodeclass to reduce the overall number of attributes to read.
If the NodeClass of all nodes is already known, the read can be further optimized to read only the attributes for a known class:
* ReadNodes(NodeIdCollection, NodeClass, out DataValueCollection, out IList<ServiceResult>, bool optionalAttributes)
* (DataValueCollection, IList<ServiceResult>) ReadNodesAsync (NodeIdCollection, NodeClass, bool optionalAttributes)
to complete async and collection operation, there is a:
* ReadNodeAsync and
* ReadValues/ReadValuesAsync
* An issue was fixed in the https async codepath, the security header was not properly set in async operation
sidenote: operation limits must be handled by caller!
Co-authored-by: Martin Regen <mregen@microsoft.com>
- set `KeepAliveTimeout` default back to 5s, was unintentionally set to 50s in 368 release
- fix a bug that duplicate subscriptions were created after reconnect when transfer succeeds.
- add a property to enable subscription transfer in reconnect, set `Session.TransferSubscriptionsOnReconnect=true` to enable, IOP issues may not allow to use it with some servers.
- add a `SessionReconnectHandler(true)` constructor to support reconnect abort, if the connection recovers before reconnect timer called. If the new constructor is used, its a breaking change: Needs check of `Session` property in Reconnect handler callback, if aborted `Session==null`.
- Reduce warning log output if server timestamp > client time.
- Add handling when subscriptions can not be transferred, e.g. when false user credentials or no security prevent transfer.
- Improve the reconnect timer handling by using `OperationLimit` in reconnect.
- Add sample for `SessionReconnectHandler` in console client.
- Seperate session sample code from `UAClient`.
- Tested on popular demo servers of various SDK vendors.
- Fix Winforms ref client