/// <summary> /// Publishes a subscription. /// </summary> public NotificationMessage GetNextMessage( OperationContext context, SessionPublishQueue queue, AsyncPublishOperation operation, out uint subscriptionId, out UInt32Collection availableSequenceNumbers, out bool moreNotifications) { subscriptionId = 0; availableSequenceNumbers = null; moreNotifications = false; NotificationMessage message = null; try { Utils.Trace("Publish #{0} ReceivedFromClient", context.ClientHandle); // check for status messages. lock (m_statusMessages) { Queue<StatusMessage> statusQueue = null; if (m_statusMessages.TryGetValue(context.SessionId, out statusQueue)) { if (statusQueue.Count > 0) { StatusMessage status = statusQueue.Dequeue(); subscriptionId = status.SubscriptionId; return status.Message; } } } bool requeue = false; do { // wait for a subscription to publish. Subscription subscription = queue.Publish( context.ClientHandle, context.OperationDeadline, requeue, operation); if (subscription == null) { Utils.Trace("Publish #{0} Timeout", context.ClientHandle); return null; } subscriptionId = subscription.Id; moreNotifications = false; // publish notifications. try { requeue = false; message = subscription.Publish( context, out availableSequenceNumbers, out moreNotifications); // a null message indicates a false alarm and that there were no notifications // to publish and that the request needs to be requeued. if (message != null) { break; } Utils.Trace("Publish False Alarm - Request #{0} Requeued.", context.ClientHandle); requeue = true; } finally { queue.PublishCompleted(subscription, moreNotifications); } } while (requeue); } finally { // update diagnostics. if (context.Session != null) { lock (context.Session.DiagnosticsLock) { SessionDiagnosticsDataType diagnostics = context.Session.SessionDiagnostics; diagnostics.CurrentPublishRequestsInQueue--; } } } return message; }