private void OnPublishComplete(IAsyncResult result)
{
PublishCallbackData callbackData = (PublishCallbackData)result.AsyncState;
try
{
Interlocked.Decrement(ref m_outstandingPublishRequests);
if (Object.ReferenceEquals(callbackData.Session, Session))
{
Interlocked.Increment(ref m_publishCount);
}
// complete request.
uint subscriptionId;
UInt32Collection availableSequenceNumbers;
bool moreNotifications;
NotificationMessage notificationMessage;
StatusCodeCollection results;
DiagnosticInfoCollection diagnosticInfos;
ResponseHeader responseHeader = callbackData.Session.EndPublish(
result,
out subscriptionId,
out availableSequenceNumbers,
out moreNotifications,
out notificationMessage,
out results,
out diagnosticInfos);
ClientBase.ValidateResponse(results, callbackData.Acknowledgements);
ClientBase.ValidateDiagnosticInfos(diagnosticInfos, callbackData.Acknowledgements);
if (diagnosticInfos != null && diagnosticInfos.Count > 0)
{
HaltTestOnError(null, "Returned non-empty DiagnosticInfos array during Publish.", null);
return;
}
// find subscription.
Subscription subscription = Find(subscriptionId);
if (subscription == null || subscription.Deleted)
{
return;
}
lock (subscription)
{
VerifyPublishResponse(
responseHeader,
subscription,
availableSequenceNumbers,
moreNotifications,
notificationMessage,
results,
diagnosticInfos);
}
// send a new request.
bool notsent = true;
if (m_stopped == 0 && Object.ReferenceEquals(callbackData.Session, Session))
{
if (m_outstandingPublishRequests < m_publishPipelineDepth)
{
BeginPublish();
notsent = false;
}
}
if (notsent)
{
Utils.Trace("Publish not sent. Count={0}, Pipeline={1}, Stopped={2}", m_outstandingPublishRequests, m_publishPipelineDepth, m_stopped);
}
}
catch (ServiceResultException e)
{
if (e.StatusCode == StatusCodes.BadNoSubscription)
{
return;
}
if (e.StatusCode == StatusCodes.BadTimeout)
{
if (!Object.ReferenceEquals(callbackData.Session, Session))
{
return;
}
Log(
"WARNING: Publish timeout. Count={0}, Pipeline={1}, SentTime={2:HH:mm:ss}, RecvTime={3:HH:mm:ss}",
m_outstandingPublishRequests,
m_publishPipelineDepth,
callbackData.Timestamp,
DateTime.UtcNow);
if (m_outstandingPublishRequests < m_publishPipelineDepth)
{
BeginPublish();
}
return;
}
HaltTestOnError(e, "Fatal error during publish.", null);
}
catch (Exception e)
{
HaltTestOnError(e, "Fatal error during publish.", null);
}
}
#endif