OPC UA Sessions, Subscriptions and Timeouts

In this article I will try to clarify all the various parameters of OPC UA communications, especially related to the various timeouts that are available.  They provide a flexible means to control the connection between the UA client and server, both on the client and server side, but it is not always very clear which parameter is which and what is the actual effect of each.

I am mostly referring to the parameters with names that are available in the UaClient object of Prosys OPC UA Java SDK. Most of these are reflecting the parameters defined in the OPC UA Specifications, but some of them are only related to the internal behavior of UaClient. In UaClient, the parameters are available via the setter and getter methods, as usual, e.g. Timeout is used via getTimeout() and setTimeout().

Sessions

All UA communications are done through sessions, which must be alive all the time in normal cases. Both the server and client can monitor the state of the session so that they will notice problems early enough and can perform proper clean up even if sessions are not not closed properly.

SessionTimeout

Sessions should not timeout very easily, so a timeout value of one hour is a good default value (the default also in UaClient). It is there just that the server can close sessions that have not been active (no message of any type from the client received for a longer period than SessionTimeout), because the client has died or is no longer connected to the server .

Timeout (i.e. service call timeout)

For individual service calls, you may use Timeout. It is typically used to check if the connection breaks, but you may also get timeouts if the server takes more time to process a service call. 10 s (10000 ms) is OK, but if your server gets loaded you may need to increase that. By default, the timeout is 0 (not used). In this case, however, the default timeout of the Java stack (2 minutes) will become effective.

StatusCheckTimeout

UaClient is monitoring the connection status to the server constantly with StatusChecks, i.e. it is polling the ServerStatus variable from the server and determining if the connection is alive and if the server is all right.

You can use the ServerStatusListener to monitor changes in the status (see below) or check the value of ServerStatus or ServerState (which is the most useful part of ServerStatus).

StatusCheckTimeout is separate from the default Timeout: it defines the timeout for the status reads only. If you get a timeout for that, ServerState is changed to CommunicationFault. Reconnect is then needed, either automatically or manually (see below).

Subscriptions

Subscriptions are used to define data acquisition from the server. The subscriptions are only loosely coupled to sessions: if the session timeouts, for example, the subscriptions can be transferred to a new session. The UaClient will perform this automatically, but you can use a few parameters to define how the subscriptions are monitored.

The most important parameters, PublishingInterval and SamplingInterval are used to define data sampling, but there are also parameters to define subscriptions status monitoring.

PublishingInterval

PublishingInterval defines how often the server checks if there are notification packages (publish responses) for a Subscription to be sent back to the client. A typical value is 1000 (ms). It should not be -1 nor 0.

Instead of using very small PublishingInterval, consider using a smaller SamplingInterval. The server may also increase the PublishingInterval to a default minimum.

SamplingInterval and QueueSize

If you wish to record samples at a faster rate than PublishingInterval, you should use the SamplingInterval of the monitored items. You will also need to reserve a longer QueueSize, to be able to keep all the samples in the server. The server can send all the samples in the queue in one notification – which is sent every PublishingInterval.

KeepAliveCount

If there is no data to send after the next PublishingInterval, the server will skip it. But KeepAlive defines how many intervals may be skipped, before an empty notification is sent anyway: to give the client a hint that the subscription is still alive in the server and that  there just has not been any data arriving to the client.

LifeTimeCount

The client’s responsibility is to send PublishRequests to the server, in order to enable the server to send PublishResponses back. The PublishResponses are used to deliver the notifications: but if there are no PublishRequests, the server cannot send a notification to the client.

The server will also verify that the client is alive by checking that new PublishRequests are received – LifeTimeCount defines the number of PublishingIntervals to wait for a new PublishRequest, before realizing that the client is no longer active. The Subscription is then removed from the server.

Republish

The notification packets are identified with a SequenceNumber. The UaClient can use these to detect if it has missed some of the notifications. If that happens, the client can make a RepublishRequest to request notifications that were missed during a communication break, for example. The server must keep the sent notifications to be able to resend, until the client has acknowledged that they were received.

PublishRequestFactor

UaClient will send several PublishRequests to the server when the first subscription is created. The server can use these, to fill in PublishResponses with new notifications. When the client receives the responses, it will send out new PublishRequests.

PubishRequestFactor determines how many requests are sent to the server: it is multiplied by the number of subscriptions to give the final number. The default value 2.

Communication breaks

If communication breaks, the server can still record new notifications, assuming that it has got enough PublishRequests in advance from the client.

In case you have 5 subscriptions and PublishRequestFactor=10, the client will send 50 PublishRequests to the server. In case of a communication break the server can send 50 PublishResponses back to the client in a normal rate. Considering a PublishingInterval of 1 s, the server can send 10 notifications for each subscription, if their items are really changing. But if the break is longer than 10 s, the server will start losing data. Unless the monitored items have a QueueSize long enough to record more samples.

Once communication is restored, the client will first call Republish to get the missing samples: after that it can send more PublishRequests and the server can continue generating new PublishResponses.

Reconnect

UaClient.reconnect() will make sure that once communication is restored, the old session is used whenever possible and that Susbcription data is not missed. You may choose to use AutoReconnect (true by default) or do it manually. AutoReconnect will make the UaClient to try to reconnect to the server every second, once the communication is broken. If you do it manually, you must be prepared to do it until it succeeds.

Queueing During Communication Break

In case of reconnect, you will also need to consider the sampling parameters such that the queues can hold all the values during the whole communication breakdown. Considering that it may easily take  half a minute to restore the connection even if it breaks down shortly, and you are sampling several times per second, you should be prepared to use QueueSize over hundred or even more for your items.

The servers will typically only use the queue as much as necessary and QueueSize defines the maximum size allowed in worst case. So you should be pretty safe to use longer queue than you need in normal circumstances.

Of course, this all is necessary only if you need to ensure that all samples are recorded in the client. If you are only interested in the current value, you can do with a QueueSize=1 and PublishRequestFactor=2 (default), which make sure that you get notified of the new value with a response time of max PublishingInterval.

Monitoring changes in your client application

UaClient defines various listener interfaces, which are used your application about these status changes.

Please, note that all the listeners are typically called asynchronously from worker threads, immediately when the respective information is available.

ServerStatusListener

The UaClient is checking the server status every StatusCheckInterval. It is doing this with a synchronous Read to the ServerStatus variable. If the read succeeds, ServerStatus is changed accordingly (ServerState is the most interesting part of ServerStatus). If the read fails (or timeouts with StatusCheckTimeout), the UaClient changes the ServerStatus to null, but provides ServerState=ServerState.CommunicationFault.

UaClient will notify about changes in these variables to every ServerStatusListener, so that you don’t need to poll it yourself. In case of a reconnect, the listeners are notified the same, whether you call reconnect() yourself or if AutoReconnect is used.

SubscriptionNotificationListener

The SubscriptionNotificationListener provides you the notification data. StatusChange is also a notification from the server that the status of the subscription has changed. For example, when the subscription is transferred to a new session, a StatusChange notification is sent to the old session.

SubscriptionAliveListener

The SubscriptionAliveListener notifies your client about the keep-alive messages and timeouts, noticed at the client side.

Leave a Reply