OPC-UA Server: How to detect non graceful client close | OPC UA Implementation: Stacks, Tools, and Samples | Forum

Avatar
Search
Forum Scope


Match



Forum Options



Minimum search word length is 3 characters - maximum search word length is 84 characters
Lost password?
sp_Feed sp_PrintTopic sp_TopicIcon
OPC-UA Server: How to detect non graceful client close
Avatar
Wilfred Nilsen
Member
Members
Forum Posts: 3
Member Since:
10/19/2020
sp_UserOfflineSmall Offline
1
10/19/2020 - 16:12
sp_Permalink sp_Print

I am working on an application where the server must know if a client is connected or not. 

I have this server code:

SessionManager sm = .....
sm.SessionActivated += EventStatus;
sm.SessionClosing += EventStatus;   // OK for graceful close, but fails for non graceful close
sm.SessionCreated += EventStatus;

The EventStatus fires for all events, including close when client closes gracefully. However, the EventStatus is not fired when the client does a non graceful shutdown (For example: unplugging the ethernet cable). In addition, sm.GetSessions() keeps returning the client. I have only had the program running for one hour after the client closed and I still get the session from sm.GetSessions(). I need to detect this condition within 5 minutes.

The server does not have a construction similar to what can be done on the client side i.e. the following is not possible on the server side:
session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);

How do I solve this problem on the server side?

Avatar
Randy Armstrong
Admin
Forum Posts: 532
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
2
10/20/2020 - 07:20
sp_Permalink sp_Print

The session does not close until the session times out.

You can control the max session timeout with a config setting but 5 minutes will likely be too fast.

This is by design because the session is not supposed to be closed until the server is sure that the client is gone for good. The timeout is the only mechanism available when a client does not shut down gracefully.

Avatar
Wilfred Nilsen
Member
Members
Forum Posts: 3
Member Since:
10/19/2020
sp_UserOfflineSmall Offline
3
10/20/2020 - 09:48
sp_Permalink sp_Print

We do not want sessions to expire, thus we have set the session timeout to the highest possible value.

We simply want to detect if the physical channel is down. Too bad you have abstracted away the possibility to find out if the physical channel (TCP) is down.

Avatar
Wilfred Nilsen
Member
Members
Forum Posts: 3
Member Since:
10/19/2020
sp_UserOfflineSmall Offline
4
10/20/2020 - 15:55
sp_Permalink sp_Print

I attempted the following solution, however neither session.Close() or session.Dispose() works. The code keeps going into the 'if" section for each iteration attempting to close the same session object. 

for(;;)
{
DateTime minTime = DateTime.UtcNow - TimeSpan.FromMinutes(5);
IList<Session> sessions = server.CurrentInstance.SessionManager.GetSessions();
for (int ii = 0; ii < sessions.Count; ii++)
{
Session session = sessions[ii];
if (session.SessionDiagnostics.ClientLastContactTime < minTime)
{
//session.Close();
session.Dispose();
}
}
Thread.Sleep(TimeSpan.FromMinutes(1));
}
Avatar
Randy Armstrong
Admin
Forum Posts: 532
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
5
10/21/2020 - 06:52
sp_Permalink sp_Print

It is a mistake to assume there is a consistent physical channel that can be monitored. When using HTTPS the sockets come and go.

If you want this type of feature you have to hook the TCP transport stack rather than look for an API at the Server application level.

There may be something on the ServerBase object you can use.

Forum Timezone: America/Phoenix
Most Users Ever Online: 202
Currently Online:
Guest(s) 24
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Forum Stats:
Groups: 2
Forums: 9
Topics: 796
Posts: 2359