Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OPC auto-reconnect pattern #16

Open
mariohr opened this issue Feb 14, 2020 · 3 comments
Open

OPC auto-reconnect pattern #16

mariohr opened this issue Feb 14, 2020 · 3 comments

Comments

@mariohr
Copy link

mariohr commented Feb 14, 2020

Hi,

how to implement a OPC auto-reconnect pattern ??

Thanks

@msalafia
Copy link
Collaborator

What do you mean exactly? please, provide more details.

@mariohr
Copy link
Author

mariohr commented Feb 17, 2020

thanks for response! today, if after start to monitoring some items and the OPC server goes down, and goes up, the client does not continue to publish values thru MQTT for example... the subscriptions and session do not reconnect ...

@msalafia
Copy link
Collaborator

msalafia commented Feb 19, 2020

Yes, this is probably due to missing reconnection mechanism in the platform. I suppose it can implemented in the following way.

In UAClient.cs try to apply the following changings:

  • Declare these two variables in the UaClient class
const int ReconnectPeriod = 10;
private SessionReconnectHandler _reconnectHandler;
  • Declare the following callback functions:
private void Client_KeepAlive(Session sender, KeepAliveEventArgs e)
        {
            if (e.Status != null && ServiceResult.IsNotGood(e.Status))
            {
                Console.WriteLine("{0} {1}/{2}", e.Status, sender.OutstandingRequestCount, sender.DefunctRequestCount);

                if (_reconnectHandler == null)
                {
                    Console.WriteLine("--- RECONNECTING ---");
                    _reconnectHandler = new SessionReconnectHandler();
                    _reconnectHandler.BeginReconnect(sender, ReconnectPeriod * 1000, Client_ReconnectComplete);
                }
            }
        }

private void Client_ReconnectComplete(object sender, EventArgs e)
        {
            // ignore callbacks from discarded objects.
            if (!Object.ReferenceEquals(sender, _reconnectHandler))
            {
                return;
            }

            var endpointUrl = _reconnectHandler.Session.Endpoint.EndpointUrl;
            _sessions[endpointUrl] = _reconnectHandler.Session; //<--- You have to remove 'readonly' from _session
            _reconnectHandler.Dispose();
            _reconnectHandler = null;

            Console.WriteLine("--- RECONNECTED ---");
        }
  • Add the following instruction in function GetSessionAsync()
private async Task<Session> GetSessionAsync(string serverUrl)
        {
            lock (_sessions)
            {
                if (_sessions.ContainsKey(serverUrl)) return _sessions[serverUrl];
            }

            await CheckAndLoadConfiguration();
            EndpointDescription endpointDescription;
            try
            {
                endpointDescription = CoreClientUtils.SelectEndpoint(serverUrl, false, 15000);
            }
            catch (Exception e)
            {
                throw new DataSetNotAvailableException();
            }
            
            Console.WriteLine("    Selected endpoint uses: {0}",
                endpointDescription.SecurityPolicyUri.Substring(endpointDescription.SecurityPolicyUri.LastIndexOf('#') + 1));

            var endpointConfiguration = EndpointConfiguration.Create(_appConfiguration);

            var endpoint = new ConfiguredEndpoint(endpointDescription.Server, endpointConfiguration);
            endpoint.Update(endpointDescription);

            var s = await Session.Create(_appConfiguration,
                                             endpoint,
                                             true,
                                             false,
                                             _appConfiguration.ApplicationName + "_session",
                                             (uint)_appConfiguration.ClientConfiguration.DefaultSessionTimeout,
                                             null,
                                             null);
            s.KeepAlive += Client_KeepAlive;  // <----- ADD THIS!!!
            
            lock (_sessions)
            {
                if (_sessions.ContainsKey(serverUrl))
                    s = _sessions[serverUrl];
                else
                    _sessions.Add(serverUrl, s);
            }

            return s;
        }

I hope this work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants