コード例 #1
0
 protected BaseWoopsaSubscriptionServiceSubscription(
     WoopsaSubscriptionChannel channel,
     WoopsaContainer root,
     int subscriptionId, string propertyPath,
     TimeSpan monitorInterval, TimeSpan publishInterval)
 {
     Channel         = channel;
     Root            = root;
     SubscriptionId  = subscriptionId;
     MonitorInterval = monitorInterval;
     PublishInterval = publishInterval;
     PropertyPath    = propertyPath;
     _lock           = new object();
     _notifications  = new List <IWoopsaNotification>();
     if (monitorInterval == WoopsaSubscriptionServiceConst.MonitorIntervalLastPublishedValueOnly &&
         publishInterval == WoopsaSubscriptionServiceConst.PublishIntervalOnce)
     {
         DoPublish();
     }
     else if (publishInterval > TimeSpan.FromMilliseconds(0))
     {
         _publishTimer           = channel.ServiceImplementation.TimerScheduler.AllocateTimer(publishInterval);
         _publishTimer.Elapsed  += _publishTimer_Elapsed;
         _publishTimer.IsEnabled = true;
     }
     else
     {
         throw new WoopsaException("A publish interval of 0 with a non-zero monitor interval is not allowed");
     }
 }
コード例 #2
0
        public WoopsaSubscriptionServiceSubscriptionServerSubClient(
            WoopsaSubscriptionChannel channel,
            WoopsaContainer root,
            int subscriptionId, string propertyPath,
            TimeSpan monitorInterval, TimeSpan publishInterval,
            WoopsaBaseClientObject subClient, string relativePropertyPath) :
            base(channel, root, subscriptionId, propertyPath, monitorInterval, publishInterval)
        {
            bool isSingleNotification =
                monitorInterval == WoopsaSubscriptionServiceConst.MonitorIntervalLastPublishedValueOnly &&
                publishInterval == WoopsaSubscriptionServiceConst.PublishIntervalOnce;
            EventHandler <WoopsaNotificationEventArgs> handler;

            if (isSingleNotification)
            {
                handler =
                    (sender, e) =>
                {
                    EnqueueNewMonitoredValue(e.Notification.Value);
                    DoPublish();     // there is not publish timer, force publishing the unique notification
                }
            }
            ;
            else
            {
                handler =
                    (sender, e) =>
                {
                    EnqueueNewMonitoredValue(e.Notification.Value);
                }
            };
            _clientSubscription = subClient.Subscribe(relativePropertyPath, handler,
                                                      monitorInterval, publishInterval);
        }
コード例 #3
0
        public int RegisterSubscription(WoopsaContainer root, bool isServerSide,
                                        string woopsaPropertyPath, TimeSpan monitorInterval, TimeSpan publishInterval)
        {
            BaseWoopsaSubscriptionServiceSubscription newSubscription;
            int subscriptionId;

            _watchClientActivity.Restart();
            lock (_idLock)
            {
                _lastSubscriptionId++;
                subscriptionId = _lastSubscriptionId;
            }
            if (isServerSide)
            {
                if (FindWoopsaClientAlongPath(root, woopsaPropertyPath,
                                              out WoopsaBaseClientObject subclient,
                                              out string relativePath))
                {
                    // subscribe directly instead of polling
                    newSubscription = new WoopsaSubscriptionServiceSubscriptionServerSubClient(
                        this, root, subscriptionId, woopsaPropertyPath, monitorInterval, publishInterval,
                        subclient, relativePath);
                }
                else
                {
                    newSubscription = new WoopsaSubscriptionServiceSubscriptionMonitorServer(
                        this, root, subscriptionId, woopsaPropertyPath, monitorInterval, publishInterval);
                }
            }
コード例 #4
0
ファイル: WoopsaExtensions.cs プロジェクト: mullerch/Woopsa
        public static IWoopsaElement ByNameOrNull(this IWoopsaContainer woopsaContainer, string name)
        {
            IWoopsaElement result;

            // For performance optimization, use directly the methods of classes WoopsaObject and WoopsaContainer
            // Complexity : O(1)
            if (woopsaContainer is WoopsaObject)
            {
                WoopsaObject woopsaObject = (WoopsaObject)woopsaContainer;
                result = woopsaObject.ByNameOrNull(name);
            }
            else if (woopsaContainer is WoopsaContainer)
            {
                WoopsaContainer container = (WoopsaContainer)woopsaContainer;
                result = container.ByNameOrNull(name);
            }
            else
            {
                // The code below can manage all the cases, but is used only for elements not
                // of type WoopsaContainer or WoopsaObject
                // Complexity : O(n)
                result = woopsaContainer.Items.ByNameOrNull(name);
                if (result == null && woopsaContainer is IWoopsaObject)
                {
                    IWoopsaObject woopsaObject = (IWoopsaObject)woopsaContainer;
                    result = woopsaObject.Properties.ByNameOrNull(name);
                    if (result == null)
                    {
                        woopsaObject.Methods.ByNameOrNull(name);
                    }
                }
            }
            return(result);
        }
コード例 #5
0
 public WoopsaSubscriptionServiceSubscriptionMonitorServer(
     WoopsaSubscriptionChannel channel,
     WoopsaContainer root,
     int subscriptionId, string propertyPath,
     TimeSpan monitorInterval, TimeSpan publishInterval) :
     base(channel, root, subscriptionId, propertyPath, monitorInterval, publishInterval)
 {
 }
コード例 #6
0
 public WoopsaContainer(WoopsaContainer container, string name)
     : base(container, name)
 {
     Lock   = new object();
     _items = new WoopsaElementList <WoopsaContainer>();
     if (Owner != null)
     {
         Owner.Add(this);
     }
 }
コード例 #7
0
 /// <summary>
 /// Create a WoopsaObjectAdapter for a fixed object reference
 /// </summary>
 /// <param name="container">Can be null if it's the root object.</param>
 /// <param name="name"></param>
 /// <param name="targetObjectGetter"></param>
 /// <param name="declaredExposedType">
 /// Type to expose for the targetObject.
 /// Specify null to use targetObject.GetType().
 /// The specified type can be different than the targetObject.GetType()
 /// when an interface is published instead of the public methods of the type.
 /// Specifying null implies that the type is determined dynamically, as targetObjectGetter
 /// does not necesarily return always the same object.
 /// </param>
 /// <param name="options"></param>
 /// <param name="defaultVisibility"></param>
 public WoopsaObjectAdapter(WoopsaContainer container, string name, object targetObject,
                            Type declaredExposedType = null,
                            WoopsaConverters customValueTypeConverters = null,
                            WoopsaObjectAdapterOptions options         = WoopsaObjectAdapterOptions.None,
                            WoopsaVisibility defaultVisibility         = DefaultDefaultVisibility) :
     this(container, name, () => targetObject, declaredExposedType,
          new TypeDescriptions(customValueTypeConverters),
          options, defaultVisibility)
 {
 }
コード例 #8
0
 internal void Add(WoopsaContainer item)
 {
     lock (Lock)
     {
         if (_items.ByNameOrNull(item.Name) != null)
         {
             throw new WoopsaException("Tried to add an item with duplicate name '" + item.Name + "' to WoopsaContainer '" + Name + "'");
         }
         _items.Add(item);
     }
 }
コード例 #9
0
 /// <summary>
 /// Create a WoopsaObjectAdapter for a dynamic object reference, returned by a delegate
 /// </summary>
 /// <param name="container"></param>
 /// <param name="name"></param>
 /// <param name="targetObjectGetter"></param>
 /// <param name="declaredExposedType">
 /// Type to expose for the targetObject.
 /// Specify null to use targetObject.GetType().
 /// The specified type can be different than the targetObject.GetType()
 /// when an interface is published instead of the public methods of the type.
 /// Specifying null implies that the type is determined dynamically, as targetObjectGetter
 /// does not necesarily return always the same object.
 /// </param>
 /// <param name="options"></param>
 /// <param name="defaultVisibility"></param>
 protected WoopsaObjectAdapter(WoopsaContainer container, string name, Func <object> targetObjectGetter,
                               Type declaredExposedType,
                               TypeDescriptions typeDescriptions,
                               WoopsaObjectAdapterOptions options = WoopsaObjectAdapterOptions.None,
                               WoopsaVisibility defaultVisibility = DefaultDefaultVisibility)
     : base(container, name)
 {
     TargetObjectGetter  = targetObjectGetter;
     DeclaredExposedType = declaredExposedType;
     DefaultVisibility   = defaultVisibility;
     Options             = options;
     TypeDescriptions    = typeDescriptions;
     _lock = new object();
 }
コード例 #10
0
 public WoopsaSubscriptionServiceImplementation(WoopsaContainer root, bool isServerSide)
 {
     _root                   = root;
     _isServerSide           = isServerSide;
     _channels               = new Dictionary <int, WoopsaSubscriptionChannel>();
     TimerScheduler          = new LightWeightTimerScheduler();
     TimerScheduler.Started += (sender, e) =>
     {
         _currentService = this;
     };
     TimerScheduler.Start();
     _timerCheckChannelTimedOut = TimerScheduler.AllocateTimer(
         WoopsaSubscriptionServiceConst.SubscriptionChannelLifeTimeCheckInterval);
     _timerCheckChannelTimedOut.Elapsed  += _timerCheckChannelTimedOut_Elapsed;
     _timerCheckChannelTimedOut.IsEnabled = true;
 }
コード例 #11
0
 public WoopsaSubscriptionServiceSubscriptionMonitor(
     WoopsaSubscriptionChannel channel,
     WoopsaContainer root,
     int subscriptionId, string propertyPath,
     TimeSpan monitorInterval, TimeSpan publishInterval) :
     base(channel, root, subscriptionId, propertyPath, monitorInterval, publishInterval)
 {
     if (monitorInterval != WoopsaSubscriptionServiceConst.MonitorIntervalLastPublishedValueOnly)
     {
         // create monitor timer
         _monitorTimer           = channel.ServiceImplementation.TimerScheduler.AllocateTimer(monitorInterval);
         _monitorTimer.Elapsed  += _monitorTimer_Elapsed;
         _monitorTimer.IsEnabled = true;
     }
     // Force immediate publishing of the current value
     DoMonitor();
     DoPublish();
 }
コード例 #12
0
        public WoopsaClient(string url, WoopsaContainer container,
                            int notificationQueueSize = DefaultNotificationQueueSize)
        {
            Uri uri = new Uri(url);

            AuthorityUrl   = uri.GetLeftPart(UriPartial.Authority);
            ClientProtocol = new WoopsaClientProtocol(url);
            _container     = container;
            WoopsaUnboundClientObject unboundRoot = CreateUnboundRoot("");

            SubscriptionChannel = new WoopsaClientSubscriptionChannel(this,
                                                                      unboundRoot, notificationQueueSize);
            _remoteMethodMultiRequest = unboundRoot.GetMethod(
                WoopsaMultiRequestConst.WoopsaMultiRequestMethodName,
                WoopsaValueType.JsonData,
                new WoopsaMethodArgumentInfo[]
            {
                new WoopsaMethodArgumentInfo(WoopsaMultiRequestConst.WoopsaMultiRequestArgumentName, WoopsaValueType.JsonData)
            });
        }
コード例 #13
0
        private bool FindWoopsaClientAlongPath(WoopsaContainer root, string path,
                                               out WoopsaBaseClientObject client, out string relativePath)
        {
            OnBeforeWoopsaModelAccess();
            try
            {
                string[]        pathParts = path.Split(WoopsaConst.WoopsaPathSeparator);
                WoopsaContainer container = root;
                bool            found     = false;

                client       = null;
                relativePath = string.Empty;
                for (int i = 0; i < pathParts.Length; i++)
                {
                    if (container is WoopsaBaseClientObject)
                    {
                        client = (WoopsaBaseClientObject)container;
                        for (int j = i; j < pathParts.Length; j++)
                        {
                            relativePath += WoopsaConst.WoopsaPathSeparator + pathParts[j];
                        }
                        found = true;
                        break;
                    }
                    else if (container == null)
                    {
                        break;
                    }
                    else if (!string.IsNullOrEmpty(pathParts[i]))
                    {
                        container = container.ByNameOrNull(pathParts[i]) as WoopsaContainer;
                    }
                }
                return(found);
            }
            finally
            {
                OnAfterWoopsaModelAccess();
            }
        }
コード例 #14
0
 internal WoopsaBaseClientObject(WoopsaClient client, WoopsaContainer container, string name, IWoopsaContainer root)
     : base(container, name)
 {
     Client = client;
     Root   = root ?? this;
 }
コード例 #15
0
ファイル: WoopsaObject.cs プロジェクト: mullerch/Woopsa
 public WoopsaObject(WoopsaContainer container, string name)
     : base(container, name)
 {
     _properties = new WoopsaElementList <WoopsaProperty>();
     _methods    = new WoopsaElementList <WoopsaMethod>();
 }
コード例 #16
0
        public WoopsaSubscriptionService(WoopsaServer server, WoopsaContainer container)
            : base(container, WoopsaSubscriptionServiceConst.WoopsaServiceSubscriptionName)
        {
            _server = server;
            _subscriptionServiceImplementation = new WoopsaSubscriptionServiceImplementation(container, true);
            _subscriptionServiceImplementation.BeforeWoopsaModelAccess +=
                (sender, e) => { server.ExecuteBeforeWoopsaModelAccess(); };
            _subscriptionServiceImplementation.AfterWoopsaModelAccess +=
                (sender, e) => { server.ExecuteAfterWoopsaModelAccess(); };
            _subscriptionServiceImplementation.CanWatch +=
                OnCanReconnectSubscriptionToNewObject;
            MethodCreateSubscriptionChannel = new WoopsaMethod(
                this,
                WoopsaSubscriptionServiceConst.WoopsaCreateSubscriptionChannel,
                WoopsaValueType.Integer,
                new WoopsaMethodArgumentInfo[] { new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaNotificationQueueSize, WoopsaValueType.Integer) },
                arguments => _subscriptionServiceImplementation.CreateSubscriptionChannel(arguments[0].ToInt32())
                );

            MethodRegisterSubscription = new WoopsaMethod(
                this,
                WoopsaSubscriptionServiceConst.WoopsaRegisterSubscription,
                WoopsaValueType.Integer,
                new WoopsaMethodArgumentInfo[] {
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaSubscriptionChannel, WoopsaValueType.Integer),
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaPropertyLink, WoopsaValueType.WoopsaLink),
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaMonitorInterval, WoopsaValueType.TimeSpan),
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaPublishInterval, WoopsaValueType.TimeSpan)
            },
                arguments =>
            {
                return(_subscriptionServiceImplementation.RegisterSubscription(
                           arguments[0].ToInt32(), arguments[1].DecodeWoopsaLocalLink(),
                           arguments[2].ToTimeSpan(), arguments[3].ToTimeSpan()));
            });

            MethodUnregisterSubscription = new WoopsaMethod(
                this,
                WoopsaSubscriptionServiceConst.WoopsaUnregisterSubscription,
                WoopsaValueType.Logical,
                new WoopsaMethodArgumentInfo[] {
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaSubscriptionChannel, WoopsaValueType.Integer),
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaSubscriptionId, WoopsaValueType.Integer)
            },
                arguments =>
            {
                return(_subscriptionServiceImplementation.UnregisterSubscription(
                           arguments[0].ToInt32(), arguments[1].ToInt32()));
            });

            MethodWaitNotification = new WoopsaMethod(
                this,
                WoopsaSubscriptionServiceConst.WoopsaWaitNotification,
                WoopsaValueType.JsonData,
                new WoopsaMethodArgumentInfo[] {
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaSubscriptionChannel, WoopsaValueType.Integer),
                new WoopsaMethodArgumentInfo(WoopsaSubscriptionServiceConst.WoopsaLastNotificationId, WoopsaValueType.Integer)
            },
                arguments =>
            {
                using (var accessFreeSection = _server.EnterModelAccessFreeSection())
                    return(new WoopsaValue(_subscriptionServiceImplementation.WaitNotification(
                                               arguments[0].ToInt32(), arguments[1].ToInt32())));
            });
        }
コード例 #17
0
 internal void Remove(WoopsaContainer item)
 {
     lock (Lock)
         _items.Remove(item);
 }
コード例 #18
0
 protected WoopsaElement(WoopsaContainer owner, string name)
 {
     Owner = owner;
     Name  = name;
 }
コード例 #19
0
 internal WoopsaUnboundClientObject(WoopsaClient client, WoopsaContainer container, string name, IWoopsaContainer root)
     : base(client, container, name, root)
 {
 }