12:55, EET
February 18, 2022
Hi,
we are using 5.0.2-105 SDK for developing opcua client and we facing a problem that the disconnect() call needs 1 minute to finish in case of a network break to server.
So could you please tell me, what is the correct way to clean up all the resources during a network break? Currently we call method removeSubscriptions(subscriptions) and disconnect(1000) in the callback method onStateChange() from class ServerStatusListener.
Thank you.
14:13, EET
April 3, 2012
Hi,
Hmm, it is possible something is not exactly correct as the default timeout for the CloseSession is 60s, but if there is no connection it should fail faster…
Anyway, is there a specific reason you are calling disconnect in the ServerStatusListener?
SDK by default handles all reconnect logic, there is no need (and you shoudn’t) to disconnect+connect each time there is a communication break. If the SDK detects a communication break, it notifies you via the ServerStatusListener, goes to a reconnect mode and notifies again when the communication has recovered. It tries to TransferSubscriptions the Subscriptions to the new Session or recreates them if they are no longer alive on the server.
Sessions have a timeout, Subscriptions have a LifetimeCount, they will be cleaned by the server side if the client doesn’t close them. You cannot clean these manually if there is a communication break (as there is no connection to the server). So basically you do not need to clean anything. (Yes, this means there is a “dying Session” on the Server until it timeouts, but typically connection breaks should be rare enough compared to the max number of sessions and the timeouts of them)
Each UaClient on connect will start an internal PublishTask Thread (though this is more like a general worker thread nowadays), a disconnect(..) will stop that. Technically it must wait possibly a tiny bit depending if it was doing something (such as just reading the ServerStatus or doing a reconnect).
P.S.
If for some reason the PublishTask Thread would take longer than 60s (basically shouldn’t happen, but this was safer than infinite Thread.join) , “Potential internal error, PublishTask Thread join 60s wait elapsed” would be logged on WARN level. If this happens let us know.
16:27, EET
February 18, 2022
Hi,
thank you for the reply. The reason why we call disconnect in onStateChange of ServerStatusListener is that we want to handle reconnect in our application, so that we have the control of the reconnect behavior. We don’t need a auto-reconnect, so we have setAutoReconnect(false). And we want to cleanup all the resources in case of network break, like end all running threads and reset the tcp connection, etc. Are there other methods beside disconnect() could do this work in this case?
P.S.
I build a test client with SampleConsoleClient, call the disconnect in onStateChange of ServerStatusListener. In case of a network break, disconnect(1000) is blocked for 20 seconds. And it seems it blocked by the lock in getSocket() call in method sendRequest() of class TcpConnection for sending the CloseSessionRequest. Could you please give me some advice how to get the disconnect in this case faster?
Thank you.
11:00, EET
April 3, 2012
That would not be a very typical way to do OPC UA. I would recommend to reconsider do you really need to do that.
Anyway, the only designed way to close the PublishTask Thread of UaClient is .disconnect. Normally if you would wish to handle reconnect manually there is UaClient.reconnect(), but it doesn’t stop PublishTask.
Technically due to historical reasons, there were separate “Stack” and “SDK” components (after 4.x there is just SDK). However, there still exists a “stack level reconnect”, which can be disabled by setting public static field com.prosysopc.ua.stack.transport.tcp.io.SecureChannelTcp.disableReconnectLogic to true. You might wish to experiment with true here. Normally I wouldn’t recommend, as it could mess up still some part of the SDK reconnect, but since you are not doing that at all, it might help.
If that doesn’t help, there is also:
static com.prosysopc.ua.stack.transport.tcp.io.TcpConnection.setSocketFactory(SocketFactory)
com.prosysopc.ua.stack.transport.tcp.io.TcpConnection.SocketFactory
com.prosysopc.ua.stack.transport.tcp.io.TcpConnection.DefaultSocketFactory, which creates com.prosysopc.ua.stack.transport.tcp.io.TcpConnection.DelegatingSocketWrapper (which just wraps a Socket)
which could be used to override the socket creation (mapping these to specific connections must be done manually).
P.S.
Note that if you e.g. try to stop everything for the purposes of unloading a component (e.g. OSGi etc.) then you also need com.prosysopc.ua.stack.utils.StackUtils.shutdown(), that will close the shared thread pools (but this should be the last interaction with the SDK, otherwise they will be re-created e.g. if there are active connections and such).
17:48, EET
February 18, 2022
Hi,
thank you for the advice. We set the disableReconnectLogic to true in our test app, and then the disconnect is faster enough despite some exception. But the comment of the variable says “Temporary flag, will be removed in some future update”. The question is how long we could use this as our solution? Another question is regarding the method setAutoReconnect of UaClient, what is that supposed to be good for, if we need to set an extra variable to disbale auto-reconnect?
Thank you.
10:14, EET
April 3, 2012
It is not possible to explain everything in detail in the scope of the forum-support, if you need more details contact sales@prosysopc.com.
The point of AutoReconnect false is that you have the option of choosing when you call client.reconnect(). It is not expected that you wouldn’t do it at all.
OPC UA is designed so that you would try to reconnect, i.e. that a tiny connection break wouldn’t lose data (as the session can potentially be activated again on a new secure channel and/or subscriptions transferred to a new session). Doing disconnect() will lose that ability as it e.g. resets the SubscriptionIds.
That flag would be removed once we remove the stack-level reconnect logic, thus there shouldn’t be an issue regarding that.
But in general we will treat the disconnect() taking so long as a bug, though fixing that … might be delayed until the stack-level reconnect is removed.
17:39, EET
February 18, 2022
Thank you for the answer. Another question regarding cleanup resources, as you mentioned that disconnect() will reset the SubscriptionIds, does it mean it is not necessary to call removeSubscriptions(subscriptions) before calling disconnect(), because disconnect() does all the work for cleanup resources?
Most Users Ever Online: 1919
Currently Online:
36 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 726
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1529
Posts: 6471
Newest Members:
gabriellabachus, Deakin, KTP25Zof, Wojciech Kubala, efrennowell431, wilfredostuart, caitlynfajardo, jeromechubb7, franciscagrimwad, adult_galleryModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0
Administrators: admin: 1