OPCFoundation / UA-.NETStandard

OPC Unified Architecture .NET Standard
Other
1.96k stars 946 forks source link

Can Session.Create use a session ID to connect to a previously undisposed session? #2068

Open lkomanetz opened 1 year ago

lkomanetz commented 1 year ago

Type of issue

Current Behavior

Application fails and does not properly dispose the OPC-UA session. When using Session.Create(...) it will create a new session with the OPC-UA server. There does not appear to be a way to see if we can connect to the session that is still on the server.

Expected Behavior

Hopeful behavior is Session.Create(...) has a way to pass in a cached session ID to see if it can connect to it. If not then the client can connect normally and have a new session created on the server.

Steps To Reproduce

N/A

Environment

- OS: N/A
- Environment: N/A
- Runtime: N/A
- Nuget Version: N/A
- Component: N/A
- Server: N/A
- Client: N/A

Anything else?

No response

ThomasNehring commented 1 year ago

When the connection between a client and server is broken, the server will keep the session alive for a certain amount of time (negotiated with the client). During this time, the client can reconnect to the still existing session. In the Opc.Ua.Client project this is realized in the SessionReconnectHandler, which is called when the keep alive request of the client are not answered within a certain period. That will create a new channel and then try to activate the still existing session. It it becomes clear that that session is no longer available, a new one will be created.

Session.Create() will always create a new session from scratch. Session.Recreate will also create a new session, but it will try to restore certain states from a template.

lkomanetz commented 1 year ago

@ThomasNehring How does that handler work in an environment where the client program is bootstrapping? Is that handler useful only when the program is still running and the connection is broken? Trying to figure out if there is a way to, during bootstrapping, recommission that session that is still there. There is a UA-Server that doesn't appear to implement the spec properly and keeps the session open even after the session timeout duration has lapsed. We have it raised with that company but no idea when they're going to get to it.

Just seeing if there is a workaround in the mean time. Thank you for the reply! I didn't know about Session.Recreate.

mregen commented 1 year ago

Hi @lkomanetz, is the issue resolved? Currently the recommended way to reconnect is by using the SessionReconnectHandler which uses the API mentioned above and which also can handle subscription transfer if supported.

lkomanetz commented 1 year ago

@mregen I'm not sure if using SessionReconnectHandler addresses the scenario above. During the runtime of the application that definitely makes sense. This scenario is for when your client application has closed unexpectedly (without properly disposing the session). Is there a way to connect to that dangling session when starting the client app after a crash before the server has disposed of it after the connection timeout has expired?

mregen commented 1 year ago

Hi @lkomanetz , the reconnect after application closed is a different scenario. I have seen prototypes doing it by saving some of the connection secrets to be able to connect to the same session. We need to provide some API or implicit function to save/restore state. --> enhancement.