Opc.Ua.Client.Session.Reconnect C# (CSharp) Method

Reconnect() public method

Reconnects to the server after a network failure.
public Reconnect ( ) : void
return void
        public void Reconnect()
        {
            try
            {
                lock (SyncRoot)
                {
                    // check if already connecting.
                    if (m_reconnecting)
                    {
                        Utils.Trace("Session is already attempting to reconnect.");

                        throw ServiceResultException.Create(
                            StatusCodes.BadInvalidState, 
                            "Session is already attempting to reconnect.");
                    }

                    Utils.Trace("Session RECONNECT starting.");
                    m_reconnecting = true;

                    // stop keep alives.
                    if (m_keepAliveTimer != null)
                    {
                        m_keepAliveTimer.Dispose();
                        m_keepAliveTimer = null;
                    }
                }

                EndpointDescription endpoint = m_endpoint.Description;

                // create the client signature.
                byte[] dataToSign = Utils.Append(endpoint.ServerCertificate, m_serverNonce);
                SignatureData clientSignature = SecurityPolicies.Sign(m_instanceCertificate, endpoint.SecurityPolicyUri, dataToSign);
                
                // check that the user identity is supported by the endpoint.
                UserTokenPolicy identityPolicy = endpoint.FindUserTokenPolicy(m_identity.TokenType, m_identity.IssuedTokenType);

                if (identityPolicy == null)
                {
                    Utils.Trace("Endpoint does not supported the user identity type provided.");

                    throw ServiceResultException.Create(
                        StatusCodes.BadUserAccessDenied,
                        "Endpoint does not supported the user identity type provided.");
                }

                // select the security policy for the user token.
                string securityPolicyUri = identityPolicy.SecurityPolicyUri;

                if (String.IsNullOrEmpty(securityPolicyUri))
                {
                    securityPolicyUri = endpoint.SecurityPolicyUri;
                }

                // need to refresh the identity (reprompt for password, refresh token).
                if (m_RenewUserIdentity != null)
                {
                    m_identity = m_RenewUserIdentity(this, m_identity);
                }

                // sign data with user token.
                UserIdentityToken identityToken = m_identity.GetIdentityToken();  
                identityToken.PolicyId = identityPolicy.PolicyId;
                SignatureData userTokenSignature = identityToken.Sign(dataToSign, securityPolicyUri);
                        
                // encrypt token.
                identityToken.Encrypt(m_serverCertificate, m_serverNonce, securityPolicyUri);                 
                
                // send the software certificates assigned to the client.
                SignedSoftwareCertificateCollection clientSoftwareCertificates = GetSoftwareCertificates();
                                
                Utils.Trace("Session REPLACING channel.");

                // check if the channel supports reconnect.
                if ((TransportChannel.SupportedFeatures & TransportChannelFeatures.Reconnect) != 0)
                {
                    TransportChannel.Reconnect();
                }
                else
                {
                    // initialize the channel which will be created with the server.
                    ITransportChannel channel = SessionChannel.Create(
                        m_configuration,
                        m_endpoint.Description,
                        m_endpoint.Configuration,
                        m_instanceCertificate,
                        MessageContext);

                    // disposes the existing channel.
                    TransportChannel = channel;
                }
                
                // reactivate session.
                byte[] serverNonce = null;
                StatusCodeCollection certificateResults = null;
                DiagnosticInfoCollection certificateDiagnosticInfos = null;
                
                Utils.Trace("Session RE-ACTIVATING session.");

                IAsyncResult result = BeginActivateSession(
                    null,
                    clientSignature,
                    null,
                    m_preferredLocales,
                    new ExtensionObject(identityToken),
                    userTokenSignature,
                    null,
                    null);

                if (!result.AsyncWaitHandle.WaitOne(5000, false))
                {
                    Utils.Trace("WARNING: ACTIVATE SESSION timed out. {1}/{0}", OutstandingRequestCount, GoodPublishRequestCount);
                }

                EndActivateSession(
                    result,
                    out serverNonce,
                    out certificateResults,
                    out certificateDiagnosticInfos);

                int publishCount = 0;

                lock (SyncRoot)
                {
                    Utils.Trace("Session RECONNECT completed successfully.");
                    m_serverNonce = serverNonce;
                    m_reconnecting = false;
                    publishCount = m_subscriptions.Count;
                }

                // refill pipeline.
                for (int ii = 0; ii < publishCount; ii++)
                {
                    BeginPublish(OperationTimeout);
                }

                StartKeepAliveTimer();
            }
            finally
            {
                m_reconnecting = false;
            }
        }