I am writing an OPC UA client using Eclipse Milo and stumbled over the following question: how does the client handle the loss of connections.
For monitoring values I do this using a subscription with the SubscriptionManager:
OpcUaClient client = myCreateClient();
List<MonitoredItemCreateRequest> items = myCreateMonitoredItems();
UaSubscription subscription = client.getSubscriptionManager().createSubscription(1_000.0).get();
List<UaMonitoredItem> result = subscription.createMonitoredItems(TimestampsToReturn.Both, items).get();
for (UaMonitoredItem item : result) {
if (!item.getStatusCode().isBad()) {
item.setValueConsumer(value -> System.out.println("Update: " + value));
}
}
Now when I restart my OPC UA server, which is also implemented using Eclipse Milo, then I do see the client reconnecting, but the subscriptions don't get any more updates. In the log I get the following output:
09:11:15.734 [ua-shared-pool-0] DEBUG o.e.m.o.s.c.s.OpcUaSubscriptionManager - Publish service failure: StatusCode{name=Bad_NoSubscription, value=0x80790000, quality=bad}
java.util.concurrent.CompletionException: UaServiceFaultException: status=Bad_NoSubscription, message=There is no subscription available for this session.
<stack-trace-omitted>
…
So it seems that OpcUaSubscriptionManager is aware of the situation, but does not try to re-register those items. Is that to be done manually?
There is a flowchart that describes the reconnect sequence a client should follow in OPC-UA Part 4, Section 6.5. It involves attempting to re-use the same secure channel, attempting to re-activate the prior session, and even attempting to transfer subscriptions to a new session if that fails. The Milo client SDK does all of this.
Restarting the server is worst-case because it throws away all the state in the process, unlike a normal network interruption. In this case the client SDK will notify via callback that its attempts to restore state after reconnect have failed and that subscriptions must be re-created manually.
Add a SubscriptionListener
to UaSubscriptionManager
and if you receive the onSubscriptionTransferFailed
callback then it's time to re-create the subscription and monitored items.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With