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

OnPublishComplete() private method

Completes an asynchronous publish operation.
private OnPublishComplete ( IAsyncResult result ) : void
result IAsyncResult
return void
        private void OnPublishComplete(IAsyncResult result)
        {
            // extract state information.
            object[] state = (object[])result.AsyncState;
            NodeId sessionId = (NodeId)state[0];
            SubscriptionAcknowledgementCollection acknowledgementsToSend = (SubscriptionAcknowledgementCollection)state[1];
            RequestHeader requestHeader = (RequestHeader)state[2];
            bool moreNotifications;
                
            AsyncRequestCompleted(result, requestHeader.RequestHandle, DataTypes.PublishRequest);

            try
            {                
                // Utils.Trace("PUBLISH #{0} RECEIVED", requestHeader.RequestHandle);

                // complete publish.
                uint subscriptionId;
                UInt32Collection availableSequenceNumbers;
                NotificationMessage notificationMessage;
                StatusCodeCollection acknowledgeResults;
                DiagnosticInfoCollection acknowledgeDiagnosticInfos;
              
                ResponseHeader responseHeader = EndPublish(
                    result, 
                    out subscriptionId,
                    out availableSequenceNumbers,
                    out moreNotifications,
                    out notificationMessage,
                    out acknowledgeResults,
                    out acknowledgeDiagnosticInfos);

                foreach (StatusCode code in acknowledgeResults)
                {
                    if (StatusCode.IsBad(code))
                    {
                        Utils.Trace("Error - Publish call finished. ResultCode={0}; SubscriptionId={1};", code.ToString(), subscriptionId);
                    }
                }
                
                // nothing more to do if session changed.
                if (sessionId != SessionId)
                {
                    Utils.Trace("Publish response discarded because session id changed: Old {0} != New {1}", sessionId, SessionId);
                    return;
                }
                
                // Utils.Trace("NOTIFICATION RECEIVED: SubId={0}, SeqNo={1}", subscriptionId, notificationMessage.SequenceNumber);

                // process response.
                ProcessPublishResponse(
                    responseHeader,
                    subscriptionId, 
                    availableSequenceNumbers, 
                    moreNotifications, 
                    notificationMessage);
                
                // nothing more to do if reconnecting.
                if (m_reconnecting)
                {
                    Utils.Trace("No new publish sent because of reconnect in progress.");
                    return;
                }
            }
            catch (Exception e)
            {
                if (m_subscriptions.Count == 0)
                {
                    // Publish responses with error should occur after deleting the last subscription.
                    Utils.Trace("Publish #{0}, Subscription count = 0, Error: {1}", requestHeader.RequestHandle, e.Message);
                }
                else
                {
                    Utils.Trace("Publish #{0}, Reconnecting={2}, Error: {1}", requestHeader.RequestHandle, e.Message, m_reconnecting);
                }
                
                moreNotifications = false;

                // ignore errors if reconnecting.
                if (m_reconnecting)
                {
                    Utils.Trace("Publish abandoned after error due to reconnect: {0}", e.Message);
                    return;
                }

                // nothing more to do if session changed.
                if (sessionId != SessionId)
                {
                    Utils.Trace("Publish abandoned after error because session id changed: Old {0} != New {1}", sessionId, SessionId);
                    return;
                }

                // try to acknowledge the notifications again in the next publish.
                if (acknowledgementsToSend != null)
                {
                    lock (SyncRoot)
                    {
                        m_acknowledgementsToSend.AddRange(acknowledgementsToSend);
                    }
                }
                                
                // raise an error event.     
                ServiceResult error = new ServiceResult(e);

                if (error.Code != StatusCodes.BadNoSubscription)
                {
                    PublishErrorEventHandler callback = null;

                    lock (m_eventLock)
                    {
                        callback = m_PublishError;
                    }

                    if (callback != null)
                    {
                        try
                        {
                            callback(this, new PublishErrorEventArgs(error));
                        }
                        catch (Exception e2)
                        {
                            Utils.Trace(e2, "Session: Unexpected error invoking PublishErrorCallback.");
                        }
                    }
                }
                
                // don't send another publish for these errors.
                switch (error.Code)
                {
                    case StatusCodes.BadNoSubscription:
                    case StatusCodes.BadSessionClosed:
                    case StatusCodes.BadTooManyPublishRequests:
                    case StatusCodes.BadServerHalted:
                    {
                        return;
                    }
                }

                Utils.Trace(e, "PUBLISH #{0} - Unhandled error during Publish.", requestHeader.RequestHandle);
            }

            int requestCount = GoodPublishRequestCount;

            if (requestCount < m_subscriptions.Count)
            {
                BeginPublish(OperationTimeout);
            }
            else
            {
                Utils.Trace("PUBLISH - Did not send another publish request. GoodPublishRequestCount={0}, Subscriptions={1}", requestCount, m_subscriptions.Count);
            }
        }