简体   繁体   中英

How to handle resubscribing after server is disconnected or restarted with OPC UA milo?

Hi I would like to know how to handle (correctly) resubscribing with OPC UA milo. Currently I use this code to create subscribtion:

private CompletableFuture<DataValue> subscribe(NodeId nodeToSubscribe, double samplingInterval, Consumer<DataValue> onChangeDo){
    CompletableFuture<DataValue> result = new CompletableFuture<>();
    try{
        //sets parameters of subscription
        ManagedSubscription subscription = ManagedSubscription.create(client, samplingInterval);
        subscription.setDefaultSamplingInterval(samplingInterval);
        subscription.setDefaultQueueSize(uint(10));

        //adds "onChange" action
        ManagedDataItem managedDataItem = subscription.createDataItem(nodeToSubscribe, item -> item.addDataValueListener(onChangeDo));

        //wait till first value was read
        ManagedDataItem.DataValueListener listener = managedDataItem.addDataValueListener(result::complete);
        result.whenComplete((v,e) -> managedDataItem.removeDataValueListener(listener));
    } catch (UaException e){
        result.completeExceptionally(e);
    }

    return result;
}

But whenever the server is restarted or the connection between client and server goes down than the subscription is not working.

I could add session activity listener and when ever the connection goes down clear the subscription manager like that (code between stars).

addSessionActivityListener(new SessionActivityListener(){
                @Override
                public void onSessionActive(UaSession session) {
                    log.info("Connecting PLC with IP address {}",ipAddress);
                        setConnectionStatus(ConnectionStatus.CONNECTED);
                        **subscribeAll();**

                }

                @Override
                public void onSessionInactive(UaSession session) {
                    log.info("Disconnecting PLC with IP address {}",ipAddress);
                    setConnectionStatus(ConnectionStatus.DISCONNECTED);
                    **uaClient.getSubscriptionManager().clearSubscriptions();**
                }
});

But maybe there is better way how to handle this. All my code can be found here GitHub

UPDATED: Based on Kevin Harron's reply I can see that it should be done automatically but I am receiving this every time the server is disconnected (my log for subscription and statusCode):

ON SUBSCRIPTION TRANSFER FAILED: subscription org.eclipse.milo.opcua.sdk.client.subscriptions.OpcUaSubscription@3f344a79, status code StatusCode{name=Bad_ServiceUnsupported, value=0x800B0000, quality=bad}

As you can see, there is probably problem, that server doesn't support transfer of subscription. Kevin advised me that this should be handled using SubscriptionListener::onSubscriptionTransferFailed so I implemented it like this:

uaClient.getSubscriptionManager().addSubscriptionListener(new UaSubscriptionManager.SubscriptionListener() {
               
                @Override
                public void onSubscriptionTransferFailed(UaSubscription subscription, StatusCode statusCode) {
                    uaClient.getSubscriptionManager().clearSubscriptions();
                    subscribeAll();

                }

It seams to work but I would like to know if this is the best way or I missed something. Thanks all for answers.

The correct approach is mostly to do nothing - all of the details of reconnecting and resubscribing are handled automatically.

The only case you need to handle is when the subscriptions were unable to be transferred after a new session was created. Implement SubscriptionListener::onSubscriptionTransferFailed to re-create any subscription this callback indicates has failed to transfer.

There's not really any other scenario where you should be manually clearing and re-creating your subscriptions. The onPublishFailure() callback is largely informational and does not require action. onSessionActive() and onSessionInactive() are purely informational and do not require any action from you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM