public WoopsaAdsProperty(WoopsaObject container, string name, WoopsaValueType type, WoopsaPropertyGet get, WoopsaPropertySet set, TcAdsSymbolInfo adsInfo) : base(container, name, type, get, set) { string[] path = adsInfo.Name.Split('.'); RootName = path[0]; AdsInfo = adsInfo; }
public WoopsaMultiRequestHandler(WoopsaObject root, WoopsaServer server) { _server = server; new WoopsaMethod(root, WoopsaMultiRequestConst.WoopsaMultiRequestMethodName, WoopsaValueType.JsonData, new List<WoopsaMethodArgumentInfo> { new WoopsaMethodArgumentInfo(WoopsaMultiRequestConst.WoopsaMultiRequestArgumentName, WoopsaValueType.JsonData) }, (s) => (HandleCall(s.ElementAt(0))) ); }
private async Task IncrementCount() { //string responsestring = await Http.GetStringAsync("http://localhost:80/woopsa/read/Signal"); //Console.WriteLine(responsestring); while (true) { response = await Http.GetJsonAsync <WoopsaObject>("http://localhost:80/woopsa/read/Signal"); currentValue = response.Value; StateHasChanged(); } }
public void TestWoopsaMultiRequest() { WoopsaObject serverRoot = new WoopsaObject(null, ""); TestObjectMultiRequest objectServer = new TestObjectMultiRequest(); WoopsaObjectAdapter adapter = new WoopsaObjectAdapter(serverRoot, "TestObject", objectServer); using (WoopsaServer server = new WoopsaServer(serverRoot)) { using (WoopsaClient client = new WoopsaClient("http://localhost/woopsa")) { ExecuteMultiRequestTestSerie(client, objectServer); } } }
public void TestWoopsaMultiRequestNoRemoteMultiRequestService() { WoopsaObject serverRoot = new WoopsaObject(null, ""); TestObjectMultiRequest objectServer = new TestObjectMultiRequest(); WoopsaObjectAdapter adapter = new WoopsaObjectAdapter(serverRoot, "TestObject", objectServer); using (WoopsaServer server = new WoopsaServer((IWoopsaContainer)serverRoot, TestingPort)) { using (WoopsaClient client = new WoopsaClient(TestingUrl)) { ExecuteMultiRequestTestSerie(client, objectServer); } } }
static void Main(string[] args) { var root = new WoopsaObject(null, "Gateway.IoT"); WoopsaClient client = new WoopsaClient("http://192.168.1.66/woopsa", root); client.Username = "******"; client.Password = "******"; client.CreateBoundRoot("device_garage"); var woopsaServer = new WoopsaServer(root, 10443); woopsaServer.Authenticator = new SimpleAuthenticator("Raspberry", (sender, e) => e.IsAuthenticated = e.Username == "admin" && e.Password == "admin"); }
public void Load() { _rootWoopsaObject = new WoopsaObject(null, "root"); _woopsaServer = new WoopsaServer(_rootWoopsaObject, port); _woopsaServer.WebServer.Routes.Add("/Pages", HTTPMethod.GET, new RouteHandlerFileSystem(folderPathWebPages)); Thread thread; #region infoDebug DiagnosticWindow.AddToDebug("\nWoopsa server listening on http://localhost:" + _woopsaServer.WebServer.Port + _woopsaServer.RoutePrefix); DiagnosticWindow.AddToDebug("Some examples of what you can do directly from your browser:"); DiagnosticWindow.AddToDebug(" * View the object hierarchy of the root object:"); DiagnosticWindow.AddToDebug(" http://localhost:" + _woopsaServer.WebServer.Port + _woopsaServer.RoutePrefix + "meta/"); DiagnosticWindow.AddToDebug(" * Read the value of a property:"); DiagnosticWindow.AddToDebug(" http://localhost:" + _woopsaServer.WebServer.Port + _woopsaServer.RoutePrefix + "read/Temperature "); DiagnosticWindow.AddToDebug(" * Surfing on the web pages found in the directory \n specified in Advanced Settings :"); DiagnosticWindow.AddToDebug(" http://localhost:" + _woopsaServer.WebServer.Port + "/Pages/ \n"); #endregion bool allThreadAreAbort; do { lock (_thisLock) { allThreadAreAbort = _allThreadAreAbort; } } while (!allThreadAreAbort); DiagnosticWindow.ResetPlcStatus(); _woopsaAdsThreadList = new List<Thread>(); lock (plcParameterList) { _shouldStop = false; } foreach (PlcParameter parameter in plcParameterList) { thread = new Thread(Start); thread.Name = "WoopsaAdsController - " + parameter.name; thread.Start(parameter); _woopsaAdsThreadList.Add(thread); } lock (_thisLock) { _allThreadAreAbort = false; } isRunning = true; }
public void TestWoopsaClientSubscriptionDisappearingProperty() { bool isValueChanged = false; MainClass objectServer = new MainClass(); InnerClass inner = new InnerClass(); objectServer.Inner = inner; using (WoopsaServer server = new WoopsaServer(objectServer, TestingPort)) { using (WoopsaClient client = new WoopsaClient(TestingUrl)) { WoopsaBoundClientObject root = client.CreateBoundRoot(); WoopsaObject Inner = root.Items.ByName(nameof(MainClass.Inner)) as WoopsaObject; WoopsaClientProperty propertyInfo = Inner.Properties.ByName(nameof(InnerClass.Info)) as WoopsaClientProperty; WoopsaClientSubscription subscription = propertyInfo.Subscribe( (sender, e) => { isValueChanged = true; }, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(20)); inner.Info = "Test"; Stopwatch watch = new Stopwatch(); watch.Start(); while ((!isValueChanged) && (watch.Elapsed < TimeSpan.FromSeconds(20))) { Thread.Sleep(10); } if (isValueChanged) { Console.WriteLine("Notification after {0} ms", watch.Elapsed.TotalMilliseconds); } else { Console.WriteLine("No notification received"); } isValueChanged = false; objectServer.Inner = new BaseInnerClass(); // objectServer.Inner = new object(); while ((!isValueChanged) && (watch.Elapsed < TimeSpan.FromSeconds(20))) { Thread.Sleep(10); } subscription.Unsubscribe(); Assert.AreEqual(true, isValueChanged); } } }
public void Load() { _rootWoopsaObject = new WoopsaObject(null, "root"); _woopsaServer = new WoopsaServer(_rootWoopsaObject, port); _woopsaServer.WebServer.Routes.Add("/Pages", HTTPMethod.GET, new RouteHandlerFileSystem(folderPathWebPages)); Thread thread; #region infoDebug DiagnosticWindow.AddToDebug("\nWoopsa server listening on http://localhost:" + _woopsaServer.WebServer.Port + _woopsaServer.RoutePrefix); DiagnosticWindow.AddToDebug("Some examples of what you can do directly from your browser:"); DiagnosticWindow.AddToDebug(" * View the object hierarchy of the root object:"); DiagnosticWindow.AddToDebug(" http://localhost:" + _woopsaServer.WebServer.Port + _woopsaServer.RoutePrefix + "meta/"); DiagnosticWindow.AddToDebug(" * Read the value of a property:"); DiagnosticWindow.AddToDebug(" http://localhost:" + _woopsaServer.WebServer.Port + _woopsaServer.RoutePrefix + "read/Temperature "); DiagnosticWindow.AddToDebug(" * Surfing on the web pages found in the directory \n specified in Advanced Settings :"); DiagnosticWindow.AddToDebug(" http://localhost:" + _woopsaServer.WebServer.Port + "/Pages/ \n"); #endregion bool allThreadAreAbort; do { lock (_thisLock) { allThreadAreAbort = _allThreadAreAbort; } }while (!allThreadAreAbort); DiagnosticWindow.ResetPlcStatus(); _woopsaAdsThreadList = new List <Thread>(); lock (plcParameterList) { _shouldStop = false; } foreach (PlcParameter parameter in plcParameterList) { thread = new Thread(Start); thread.Name = "WoopsaAdsController - " + parameter.name; thread.Start(parameter); _woopsaAdsThreadList.Add(thread); } lock (_thisLock) { _allThreadAreAbort = false; } isRunning = true; }
public void TestWoopsaObjectPerformance() { const int ObjectCount = 5000; const int AccessCount = 50000; WoopsaRoot root = new WoopsaRoot(); for (int i = 0; i < ObjectCount; i++) { WoopsaObject newObject = new WoopsaObject(root, "Item" + i.ToString()); int x = i; new WoopsaProperty(newObject, "Data", WoopsaValueType.Integer, (p) => x); } Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < AccessCount; i++) { int k = ((WoopsaProperty)(root.ByPath("Item" + (ObjectCount - 1).ToString() + "/Data"))).Value.ToInt32(); } Assert.IsTrue(watch.ElapsedMilliseconds < 1000); }
public void TestWoopsaObjects() { WoopsaRoot root = new WoopsaRoot(); WoopsaObject tunnel1 = new WoopsaObject(root, "Tunnel1"); Assert.AreEqual(root.Items.Count(), 1); WoopsaObject tunnel2 = new WoopsaObject(root, "Tunnel2"); Assert.AreEqual(root.Items.Count(), 2); WoopsaObject coMessung1 = new WoopsaObject(tunnel1, "CoMessung1"); Assert.AreEqual(coMessung1.GetPath(), "/Tunnel1/CoMessung1"); WoopsaProperty property1 = new WoopsaProperty(coMessung1, "Level", WoopsaValueType.Real, (sender) => 1040.0); int property2Value = 0; WoopsaProperty property2 = new WoopsaProperty(coMessung1, "Variation", WoopsaValueType.Real, (sender) => property2Value, (sender, value) => property2Value = value.ToInt32()); Assert.AreEqual(coMessung1.Properties.Count(), 2); Assert.AreEqual(coMessung1.Properties.First().Value.ToDouble(), 1040.0); coMessung1.Properties.ByName("Variation").Value = 45; Assert.AreEqual(coMessung1.Properties.ByName("Variation").Value.ToInt32(), 45); Assert.AreEqual(coMessung1.Properties.ByName("Variation").Value.ToString(), "45"); (coMessung1.ByName("Variation") as IWoopsaProperty).Value = (WoopsaValue)36; Assert.AreEqual(coMessung1.Properties.ByName("Variation").Value.ToInt32(), 36); coMessung1.Properties["Variation"].Value = 5; Assert.AreEqual(property2Value, 5); int variation = coMessung1.Properties["Variation"].Value; Assert.AreEqual(variation, 5); WoopsaMethod method1 = new WoopsaMethod(coMessung1, "Calibrate", WoopsaValueType.Null, new WoopsaMethodArgumentInfo[] { new WoopsaMethodArgumentInfo("minLevel", WoopsaValueType.Real), new WoopsaMethodArgumentInfo("maxLevel", WoopsaValueType.Real) }, Calibrate); IWoopsaValue result = method1.Invoke(1.1, 5.5); Assert.AreEqual(result, WoopsaValue.Null); Assert.AreEqual(_minLevel, 1.1); Assert.AreEqual(_maxLevel, 5.5); }
public void TestWoopsaObjectPerformance() { const int objectCount = 5000; const int accessCount = 50000; WoopsaRoot root = new WoopsaRoot(); for (int i = 0; i < objectCount; i++) { WoopsaObject newObject = new WoopsaObject(root, "Item" + i.ToString()); int x = i; new WoopsaProperty(newObject, "Data", WoopsaValueType.Integer, (p) => x); } Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < accessCount; i++) { int k = ((WoopsaProperty)(root.ByPath("Item" + (objectCount - 1).ToString() + "/Data"))).Value.ToInt32(); } Assert.IsTrue(watch.ElapsedMilliseconds < 1000); }
public void TestWoopsaClientSubscriptionChannelNoRemoteSubscriptionService() { bool isValueChanged = false; WoopsaObject objectServer = new WoopsaObject(null, ""); int votes = 0; WoopsaProperty propertyVotes = new WoopsaProperty(objectServer, "Votes", WoopsaValueType.Integer, (p) => votes, (p, value) => { votes = value.ToInt32(); }); using (WoopsaServer server = new WoopsaServer((IWoopsaContainer)objectServer, TestingPort)) { using (WoopsaClient client = new WoopsaClient(TestingUrl)) { WoopsaBoundClientObject root = client.CreateBoundRoot(); WoopsaClientSubscription subscription = root.Subscribe(nameof(TestObjectServer.Votes), (sender, e) => { isValueChanged = true; }, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(20)); votes = 2; Stopwatch watch = new Stopwatch(); watch.Start(); while ((!isValueChanged) && (watch.Elapsed < TimeSpan.FromSeconds(2000))) { Thread.Sleep(10); } if (isValueChanged) { Console.WriteLine("Notification after {0} ms", watch.Elapsed.TotalMilliseconds); } else { Console.WriteLine("No notification received"); } subscription.Unsubscribe(); Assert.AreEqual(true, isValueChanged); } } }
public void Start(object argsObject) { PlcParameter plcParameter = argsObject as PlcParameter; try { WoopsaAdsServer serverConnection = new WoopsaAdsServer(plcParameter.adsNetId); WoopsaProperty propertyIsConnected; WoopsaObject plc = null; bool isWorking = false; bool shouldShutDown = false; lock (_rootWoopsaObject) { DiagnosticWindow.AddPlcStatus(new PlcStatus(plcParameter.name, false, "Starting up")); propertyIsConnected = new WoopsaProperty(_rootWoopsaObject, "IsAlive" + plcParameter.name, WoopsaValueType.Logical, (property) => serverConnection.isAdsConnected); } while (!shouldShutDown) { if (serverConnection.IsHeartBeatAlive()) { serverConnection.isAdsConnected = true; if (!serverConnection.isHierarchieLoaded) { if (plc != null) { plc.Dispose(); } lock (_rootWoopsaObject) { plc = new WoopsaObject(_rootWoopsaObject, plcParameter.name); } serverConnection.loadHierarchy(plc); } if (!isWorking) { isWorking = true; DiagnosticWindow.AddToDebug(Thread.CurrentThread.Name + " thread : working..."); lock (_rootWoopsaObject) { DiagnosticWindow.PlcStatusChange(plc.Name, isWorking, "Working"); } } } else { serverConnection.isAdsConnected = false; serverConnection.isHierarchieLoaded = false; if (plc != null) { plc.Dispose(); } DiagnosticWindow.AddToDebug(Thread.CurrentThread.Name + " - Error connection ... Try again"); isWorking = false; lock (_rootWoopsaObject) { DiagnosticWindow.PlcStatusChange(plcParameter.name, isWorking, "Error"); } } Thread.Sleep(500); lock (plcParameterList) { shouldShutDown = _shouldStop; } } serverConnection.Dispose(); } catch (SocketException e) { // A SocketException is caused by an application already listening on a port in 90% of cases // Applications known to use port 80: // - On Windows 10, IIS is on by default on some configurations. Disable it here: // http://stackoverflow.com/questions/30758894/apache-server-xampp-doesnt-run-on-windows-10-port-80 // - IIS // - Apache // - Nginx // - Skype DiagnosticWindow.AddToDebug("Error: Could not start Woopsa Server. Most likely because an application is already listening on port 80."); DiagnosticWindow.AddToDebug("Known culprits:"); DiagnosticWindow.AddToDebug(" - On Windows 10, IIS is on by default on some configurations."); DiagnosticWindow.AddToDebug(" - Skype"); DiagnosticWindow.AddToDebug(" - Apache, nginx, etc."); DiagnosticWindow.AddToDebug("SocketException: " + e.Message); MessageBox.Show("SocketException ! : See diagnostic log for more information", "Er ror", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception ex) { Application.Current.Dispatcher.Invoke( System.Windows.Threading.DispatcherPriority.Normal, new Action <Exception>((exc) => { throw new Exception("Exception from another Thread : " + Thread.CurrentThread.Name, exc); }), ex); } DiagnosticWindow.AddToDebug(Thread.CurrentThread.Name + " thread: terminating gracefully."); lock (_rootWoopsaObject) { lock (App.appLock) { if (App.isExiting) { return; } } DiagnosticWindow.PlcStatusChange(plcParameter.name, false, "Stop"); } }
public void TestWoopsaWaitNotification() { TestObjectServer objectServer = new TestObjectServer(); using (WoopsaServer server = new WoopsaServer(objectServer, TestingPort)) { using (WoopsaClient client = new WoopsaClient(TestingUrl)) { WoopsaBoundClientObject root = client.CreateBoundRoot(); // Just to show how to see all items foreach (var item in root.Items) { Console.WriteLine("Item = " + item.Name); if (item.Name == "SubscriptionService") { Console.WriteLine("Trouvé"); } } // create a subscription object WoopsaObject subscription = root.Items.ByNameOrNull("SubscriptionService") as WoopsaObject; if (subscription != null) { int result = 0; WoopsaMethod methodCreateScubscriptionChannel = subscription.Methods.ByNameOrNull("CreateSubscriptionChannel"); if (methodCreateScubscriptionChannel != null) { // call the method "CreateSubscriptionChannel" on the server result = methodCreateScubscriptionChannel.Invoke(1000); // define the queue size } int channel = result; WoopsaMethod methodRegisterScubscription = subscription.Methods.ByNameOrNull("RegisterSubscription"); if (methodRegisterScubscription != null) { // call the method "registerScubscription" on the server result = methodRegisterScubscription.Invoke(channel, WoopsaValue.WoopsaRelativeLink("/Votes"), 0.01, 0.01); } int subscriptionNbr = result; WoopsaJsonData jData; WoopsaMethod methodWaitNotification = subscription.Methods.ByNameOrNull("WaitNotification"); if (methodWaitNotification != null) { Stopwatch watch = new Stopwatch(); watch.Start(); // call the method "WaitNotification" on the server Thread.Sleep(100); jData = methodWaitNotification.Invoke(channel, 0).JsonData; Assert.IsTrue(jData.Length > 0); int lastNotification; lastNotification = jData[0]["Id"]; Assert.AreEqual(lastNotification, 1); // Get notifications again Thread.Sleep(100); jData = methodWaitNotification.Invoke(channel, 0).JsonData; Assert.IsTrue(jData.Length > 0); lastNotification = jData[0]["Id"]; Assert.AreEqual(lastNotification, 1); } } } } }
public void TestWoopsaClientSubscriptionChannelNoRemoteSubscriptionService() { bool isValueChanged = false; WoopsaObject objectServer = new WoopsaObject(null, ""); int Votes = 0; WoopsaProperty propertyVotes = new WoopsaProperty(objectServer, "Votes", WoopsaValueType.Integer, (p) => Votes, (p, value) => { Votes = value.ToInt32(); }); using (WoopsaServer server = new WoopsaServer((IWoopsaContainer)objectServer)) { using (WoopsaClient client = new WoopsaClient("http://localhost/woopsa")) { WoopsaBoundClientObject root = client.CreateBoundRoot(); WoopsaClientSubscription subscription = root.Subscribe(nameof(TestObjectServer.Votes), (sender, e) => { isValueChanged = true; }, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(20)); Votes = 2; Stopwatch watch = new Stopwatch(); watch.Start(); while ((!isValueChanged) && (watch.Elapsed < TimeSpan.FromSeconds(2000))) Thread.Sleep(10); if (isValueChanged) Console.WriteLine("Notification after {0} ms", watch.Elapsed.TotalMilliseconds); else Console.WriteLine("No notification received"); subscription.Unsubscribe(); Assert.AreEqual(true, isValueChanged); } } }
public void TestWoopsaMultiRequestNoRemoteMultiRequestService() { WoopsaObject serverRoot = new WoopsaObject(null, ""); TestObjectMultiRequest objectServer = new TestObjectMultiRequest(); WoopsaObjectAdapter adapter = new WoopsaObjectAdapter(serverRoot, "TestObject", objectServer); using (WoopsaServer server = new WoopsaServer((IWoopsaContainer)serverRoot)) { using (WoopsaClient client = new WoopsaClient("http://localhost/woopsa")) { ExecuteMultiRequestTestSerie(client, objectServer); } } }
public WoopsaAdsProperty(WoopsaObject container, string name, WoopsaValueType type, WoopsaPropertyGet get, TcAdsSymbolInfo adsInfo) : this(container, name, type, get, null, adsInfo) { }
public void loadHierarchy(WoopsaObject root) { try { _symbolLoader = _tcAds.CreateSymbolInfoLoader(); _woopsaObjects = new Dictionary<string, WoopsaObject>(); _woopsaProperties = new Dictionary<string, WoopsaAdsProperty>(); foreach (TcAdsSymbolInfo symbol in _symbolLoader) { WoopsaObject newObject = null; WoopsaAdsProperty newProperty = null; TcAdsSymbolInfo parentInfo; WoopsaValueType propertyType; string[] path = symbol.Name.Split('.'); string name = path[path.Length - 1]; bool isProperties = BeckhoffToWoopsaValueType(symbol.Type, out propertyType); if (symbol.Parent != null) { parentInfo = symbol.Parent; if (_woopsaObjects.ContainsKey(parentInfo.Name)) { if (isProperties) { newProperty = new WoopsaAdsProperty(_woopsaObjects[parentInfo.Name], name, propertyType, _woopsaAdsPropertyGet, _woopsaAdsPropertySet, symbol); } else newObject = new WoopsaObject(_woopsaObjects[parentInfo.Name], name); } else { throw new Exception("Parent WoopsaObject not found !"); } } else { if (isProperties) { newProperty = new WoopsaAdsProperty(root, name, propertyType, _woopsaAdsPropertyGet, _woopsaAdsPropertySet, symbol); } else newObject = new WoopsaObject(root, name); } if (isProperties) _woopsaProperties.Add(symbol.Name, newProperty); else _woopsaObjects.Add(symbol.Name, newObject); } }catch(Exception e) { DiagnosticWindow.AddToDebug(e.Message); } isHierarchieLoaded = true; }
/// <summary> /// Creates an instance of the Woopsa server adding multiRequestHandler and SubscriptionService /// /// It will automatically create the required HTTP server /// on the specified port and will prefix woopsa verbs with the specified /// route prefix. It will also add all the necessary native extensions for /// Publish/Subscribe and Mutli-Requests. /// </summary> /// <param name="root">The root object that will be published via Woopsa.</param> /// <param name="port">The port on which to run the web server</param> /// <param name="routePrefix"> /// The prefix to add to all routes for woopsa verbs. For example, specifying /// "myPrefix" will make the server available on http://server/myPrefix /// </param> public WoopsaServer(WoopsaObject root, int port = DefaultPort, string routePrefix = DefaultServerPrefix) : this((IWoopsaContainer)root, port, routePrefix) { new WoopsaMultiRequestHandler(root, this); _subscriptionService = new WoopsaSubscriptionService(this, root); }
public void loadHierarchy(WoopsaObject root) { try { _symbolLoader = _tcAds.CreateSymbolInfoLoader(); _woopsaObjects = new Dictionary <string, WoopsaObject>(); _woopsaProperties = new Dictionary <string, WoopsaAdsProperty>(); foreach (TcAdsSymbolInfo symbol in _symbolLoader) { WoopsaObject newObject = null; WoopsaAdsProperty newProperty = null; TcAdsSymbolInfo parentInfo; WoopsaValueType propertyType; string[] path = symbol.Name.Split('.'); string name = path[path.Length - 1]; bool isProperties = BeckhoffToWoopsaValueType(symbol.Type, out propertyType); if (symbol.Parent != null) { parentInfo = symbol.Parent; if (_woopsaObjects.ContainsKey(parentInfo.Name)) { if (isProperties) { newProperty = new WoopsaAdsProperty(_woopsaObjects[parentInfo.Name], name, propertyType, _woopsaAdsPropertyGet, _woopsaAdsPropertySet, symbol); } else { newObject = new WoopsaObject(_woopsaObjects[parentInfo.Name], name); } } else { throw new Exception("Parent WoopsaObject not found !"); } } else { if (isProperties) { newProperty = new WoopsaAdsProperty(root, name, propertyType, _woopsaAdsPropertyGet, _woopsaAdsPropertySet, symbol); } else { newObject = new WoopsaObject(root, name); } } if (isProperties) { _woopsaProperties.Add(symbol.Name, newProperty); } else { _woopsaObjects.Add(symbol.Name, newObject); } } }catch (Exception e) { DiagnosticWindow.AddToDebug(e.Message); } isHierarchieLoaded = true; }
public void Start(object argsObject) { PlcParameter plcParameter = argsObject as PlcParameter; try { WoopsaAdsServer serverConnection = new WoopsaAdsServer(plcParameter.adsNetId); WoopsaProperty propertyIsConnected; WoopsaObject plc = null; bool isWorking = false; bool shouldShutDown = false; lock (_rootWoopsaObject) { DiagnosticWindow.AddPlcStatus(new PlcStatus(plcParameter.name, false, "Starting up")); propertyIsConnected = new WoopsaProperty(_rootWoopsaObject, "IsAlive" + plcParameter.name, WoopsaValueType.Logical, (property) => serverConnection.isAdsConnected); } while (!shouldShutDown) { if (serverConnection.IsHeartBeatAlive()) { serverConnection.isAdsConnected = true; if (!serverConnection.isHierarchieLoaded) { if (plc != null) { plc.Dispose(); } lock (_rootWoopsaObject) { plc = new WoopsaObject(_rootWoopsaObject, plcParameter.name); } serverConnection.loadHierarchy(plc); } if (!isWorking) { isWorking = true; DiagnosticWindow.AddToDebug(Thread.CurrentThread.Name + " thread : working..."); lock (_rootWoopsaObject) { DiagnosticWindow.PlcStatusChange(plc.Name, isWorking, "Working"); } } } else { serverConnection.isAdsConnected = false; serverConnection.isHierarchieLoaded = false; if (plc != null) { plc.Dispose(); } DiagnosticWindow.AddToDebug(Thread.CurrentThread.Name + " - Error connection ... Try again"); isWorking = false; lock (_rootWoopsaObject) { DiagnosticWindow.PlcStatusChange(plcParameter.name, isWorking, "Error"); } } Thread.Sleep(500); lock (plcParameterList) { shouldShutDown = _shouldStop; } } serverConnection.Dispose(); } catch (SocketException e) { // A SocketException is caused by an application already listening on a port in 90% of cases // Applications known to use port 80: // - On Windows 10, IIS is on by default on some configurations. Disable it here: // http://stackoverflow.com/questions/30758894/apache-server-xampp-doesnt-run-on-windows-10-port-80 // - IIS // - Apache // - Nginx // - Skype DiagnosticWindow.AddToDebug("Error: Could not start Woopsa Server. Most likely because an application is already listening on port 80."); DiagnosticWindow.AddToDebug("Known culprits:"); DiagnosticWindow.AddToDebug(" - On Windows 10, IIS is on by default on some configurations."); DiagnosticWindow.AddToDebug(" - Skype"); DiagnosticWindow.AddToDebug(" - Apache, nginx, etc."); DiagnosticWindow.AddToDebug("SocketException: " + e.Message); MessageBox.Show("SocketException ! : See diagnostic log for more information", "Er ror", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception ex) { Application.Current.Dispatcher.Invoke( System.Windows.Threading.DispatcherPriority.Normal, new Action<Exception>((exc) => { throw new Exception("Exception from another Thread : " + Thread.CurrentThread.Name, exc); }), ex); } DiagnosticWindow.AddToDebug(Thread.CurrentThread.Name + " thread: terminating gracefully."); lock (_rootWoopsaObject) { lock (App.appLock) { if (App.isExiting) return; } DiagnosticWindow.PlcStatusChange(plcParameter.name, false, "Stop"); } }