Opc.Ua.ServerTest.SubscribeTest.VerifyPublishResponse C# (CSharp) Method

VerifyPublishResponse() private method

Verifies the result of a publish
private VerifyPublishResponse ( ResponseHeader responseHeader, Subscription subscription, UInt32Collection availableSequenceNumbers, bool moreNotifications, NotificationMessage notificationMessage, StatusCodeCollection results, DiagnosticInfoCollection diagnosticInfos ) : bool
responseHeader ResponseHeader
subscription Subscription
availableSequenceNumbers UInt32Collection
moreNotifications bool
notificationMessage NotificationMessage
results StatusCodeCollection
diagnosticInfos DiagnosticInfoCollection
return bool
        private bool VerifyPublishResponse(
            ResponseHeader responseHeader,
            Subscription subscription,
            UInt32Collection availableSequenceNumbers,
            bool moreNotifications,
            NotificationMessage notificationMessage,
            StatusCodeCollection results,
            DiagnosticInfoCollection diagnosticInfos)
        {
            /*
            Utils.Trace(
                "PublishReceived: SubId={0} SeqNo={1}, PublishTime={2:mm:ss.fff}, Time={3:mm:ss.fff}",
                subscription.SubscriptionId,
                notificationMessage.SequenceNumber,
                notificationMessage.PublishTime,
                DateTime.UtcNow);
            */

            // check if there is an odd delay.
            if (responseHeader.Timestamp > notificationMessage.PublishTime.AddMilliseconds(100))
            {
                Log(
                    "WARNING. Unexpected delay between PublishTime and ResponseTime. SeqNo={0}, PublishTime={1:hh:mm:ss.fff}, ResponseTime={2:hh:mm:ss.fff}",
                    notificationMessage.SequenceNumber,
                    notificationMessage.PublishTime,
                    responseHeader.Timestamp);
            }

            // save results.
            subscription.AvailableSequenceNumbers = availableSequenceNumbers;

            if (notificationMessage.NotificationData.Count == 0)
            {
                // keep alives do not increment the sequence number.
                if (subscription.NextExpectedSequenceNumber != notificationMessage.SequenceNumber)
                {
                    Log(
                        "Incorrect sequence number for keep alive. SubscriptionId = {0}, Actual = {1}, Expected = {2}", 
                        subscription.SubscriptionId,
                        notificationMessage.SequenceNumber,
                        subscription.NextExpectedSequenceNumber);

                    subscription.Failed = true;
                    return false;
                }

                // save the message.                
                DateTime timestamp = responseHeader.Timestamp;
                DateTime start = subscription.States[subscription.States.Count - 1].Start;

                // check if this is an old request being processed late.
                if (start > timestamp && subscription.States.Count > 1)
                {
                    subscription.States[subscription.States.Count - 2].KeepAlives.Add(timestamp);
                }
                else
                {
                    subscription.States[subscription.States.Count - 1].KeepAlives.Add(timestamp);
                }
            }
            else
            {
                // check for replays.
                if (subscription.NextExpectedSequenceNumber > notificationMessage.SequenceNumber)
                {
                    // check for out of order responses.
                    bool found = false;

                    for (int ii = 0; ii < subscription.MissingSequenceNumbers.Count; ii++)
                    {
                        if (subscription.MissingSequenceNumbers[ii] == notificationMessage.SequenceNumber)
                        {
                            subscription.MissingSequenceNumbers.RemoveAt(ii);
                            found = true;
                            break;
                        }
                    }

                    // oops - duplicate.
                    if (!found)
                    {
                        Log(
                            "Duplicate sequence number for message. SubscriptionId = {0}, Actual = {1}, Expected = {2}",
                            subscription.SubscriptionId,
                            notificationMessage.SequenceNumber,
                            subscription.NextExpectedSequenceNumber);

                        subscription.Failed = true;
                        return false;
                    }
                }
                
                // increment message counter.
                if (notificationMessage.SequenceNumber >= subscription.NextExpectedSequenceNumber)
                {
                    for (uint ii = subscription.NextExpectedSequenceNumber; ii < notificationMessage.SequenceNumber; ii++)
                    {
                        if (!subscription.MissingSequenceNumbers.Contains(ii))
                        {
                            subscription.MissingSequenceNumbers.Add(ii);
                        }
                    }

                    subscription.NextExpectedSequenceNumber = notificationMessage.SequenceNumber+1;
                }
                                                        
                // save the largest received message number (gap exist because of client side threading issues).
                if (subscription.LastReceivedSequenceNumber < notificationMessage.SequenceNumber)
                {
                    subscription.LastReceivedSequenceNumber = notificationMessage.SequenceNumber;
                }

                // save the message.                
                DateTime timestamp = responseHeader.Timestamp;
                DateTime start = subscription.States[subscription.States.Count-1].Start;

                // check if this is an old request being processed late.
                if (start > timestamp && subscription.States.Count > 1)
                {
                    subscription.States[subscription.States.Count - 2].KeepAlives.Add(timestamp);
                }
                else
                {
                    subscription.States[subscription.States.Count - 1].KeepAlives.Add(timestamp);
                }

                subscription.NotificationMessages.Add(notificationMessage);
                subscription.ReceiveTimes.Add(responseHeader.Timestamp);

                // change to keep alive mode.
                if (subscription.StaticData)
                {
                    PublishingState state = new PublishingState();

                    state.KeepAliveCount = subscription.KeepAliveCount;
                    state.PublishingInterval = subscription.PublishingInterval;
                    state.Start = timestamp;
                    state.KeepAliveMode = true;

                    subscription.States[subscription.States.Count-1].End = state.Start;
                    subscription.States.Add(state);
                }

                // save the acknowlegements.
                SaveAcknowledgement(subscription.SubscriptionId, notificationMessage.SequenceNumber);
            }

            return true;
        }