Beispiel #1
0
        /// <summary>
        /// Dispatches a notification message produced by a subscription.
        /// </summary>
        private void DispatchMessage(Subscription subscription, NotificationMessage notification)
        {
            lock (m_messages)
            {
                for (LinkedListNode<QueuedRequest> node = m_requests.First; node != null; node = node.Next)
                {
                    // wake up timed out requests and force them to return a fault.
                    if (node.Value.Timeout < DateTime.UtcNow)
                    {
                        node.Value.Signal.Set();
                        m_requests.Remove(node);
                        continue;
                    }

                    // check for a request that matches the session.
                    if (Object.ReferenceEquals(subscription.Session, node.Value.Session))
                    {
                        // pass the message to the request and wake up the request thread.
                        node.Value.SubscriptionId = subscription.Id;
                        node.Value.Message = notification;
                        node.Value.Signal.Set();
                        m_requests.Remove(node);
                        return;
                    }
                }

                // messages only go on the publish queue if no threads are waiting.
                QueuedMessage message = new QueuedMessage();

                message.Session = subscription.Session;
                message.Subscription = subscription;
                message.Message = notification;
                m_messages.AddLast(message);

                // ensure queue does not grow too large.
                while (m_messages.Count > 50)
                {
                    m_messages.RemoveFirst();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates a subscription that can be used to recieve data change or event notifications. 
        /// </summary>
        public CreateSubscriptionResponseMessage CreateSubscription(CreateSubscriptionMessage request)
        {
            try
            {
                lock (m_lock)
                {
                    // verify the session.
                    Session session = VerifySession(request.RequestHeader, false);

                    // create a new subscription.
                    Subscription subscription = new Subscription();

                    uint subscriptionId;
                    double publishingInterval;
                    uint lifetimeCount;
                    uint keepAliveCount;

                    // the subscription validates the parameters and throws exceptions on error.
                    subscription.Create(
                        session,
                        m_nodeManager,
                        request.RequestedPublishingInterval,
                        request.RequestedLifetimeCount,
                        request.RequestedMaxKeepAliveCount,
                        request.MaxNotificationsPerPublish,
                        request.PublishingEnabled,
                        request.Priority,
                        out subscriptionId,
                        out publishingInterval,
                        out lifetimeCount,
                        out keepAliveCount);

                    // save the subscription.
                    m_subscriptions.Add(subscriptionId, subscription);

                    // start the publish thread if it has not already been started.
                    if (m_subscriptions.Count == 1)
                    {
                        ThreadPool.QueueUserWorkItem(PublishSubscriptions);
                    }

                    // return the response.
                    CreateSubscriptionResponseMessage response = new CreateSubscriptionResponseMessage();

                    response.ResponseHeader = CreateResponseHeader(request.RequestHeader);
                    response.SubscriptionId = subscriptionId;
                    response.RevisedPublishingInterval = publishingInterval;
                    response.RevisedLifetimeCount = lifetimeCount;
                    response.RevisedMaxKeepAliveCount = keepAliveCount;

                    return response;
                }
            }
            catch (Exception e)
            {
                throw CreateSoapFault(request.RequestHeader, e);
            }
        }