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"); }
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; }
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) }); }
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(); }; 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())); }); }
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); }
public WoopsaSubscriptionServiceSubscriptionMonitorServer( WoopsaSubscriptionChannel channel, WoopsaContainer root, int subscriptionId, string propertyPath, TimeSpan monitorInterval, TimeSpan publishInterval) : base(channel, root, subscriptionId, propertyPath, monitorInterval, publishInterval) { }
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(); }
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(); } }
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) { WoopsaBaseClientObject subclient; string relativePath; if (FindWoopsaClientAlongPath(root, woopsaPropertyPath, out subclient, out 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); } else newSubscription = new WoopsaSubscriptionServiceSubscriptionMonitorClient( this, (WoopsaBaseClientObject)root, subscriptionId, woopsaPropertyPath, monitorInterval, publishInterval); lock (_subscriptions) _subscriptions.Add(newSubscription.SubscriptionId, newSubscription); return newSubscription.SubscriptionId; }
internal WoopsaUnboundClientObject(WoopsaClient client, WoopsaContainer container, string name, IWoopsaContainer root) : base(client, container, name, root) { }
internal WoopsaBaseClientObject(WoopsaClient client, WoopsaContainer container, string name, IWoopsaContainer root) : base(container, name) { Client = client; Root = root ?? this; }