using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using Maser.Feanor.Model; using Maser.Feanor.Biz; using Maser.Feanor.Server; using System.Net; namespace Maser.Feanor.Client { public class ClientWorker { public ClientWorker(Chamber Chamber) { _Chamber = Chamber; ThreadPool.SetMaxThreads(1000, 1000); _thread = null; _status = ChamberStatus.Init; try { _Server = Servers.GetInstanceByChamber(_Chamber); } catch (Exception ex) { string s = "class ClientWorker->Servers.GetInstanceByChamber() (chamber: " + _Chamber.ToString() + ")\n Exception: " + ex.Message; throw new Exception(s); } } private Thread _thread; public ChamberStatus Status { get { return _status; } } private ChamberStatus _status; private Boolean _isKicking; public DateTime LastKick { get { return _lastKick; } } private DateTime _lastKick; public DateTime LastHTTP { get { return _LastHTTP; } } private DateTime _LastHTTP; private DateTime _LastDBWrite; // Used for detecting idling of server Int32 _KickIntervalms = 60000; // Normal interval for contenttoclient request --> 1 minute Int32 interval = 5000; // Interval for first contenttoclient request --> 5 seconds private Server.Server _Server; public Server.Server Server { get { return _Server; } } private Chamber _Chamber; public Chamber Chamber { get { return _Chamber; } } public bool IsRunning { get { return (_thread != null) && _thread.IsAlive && _isKicking; } } public bool Start() { if (!IsRunning) { _status = ChamberStatus.Initializing; _thread = new Thread(new ThreadStart(ThreadFunction)); _thread.Start(); return true; } return false; } public bool Stop() { DateTime OnStop = DateTime.Now; _status = ChamberStatus.AbortRequested; // De-set _isStarted and wait max 10 seconds for result. while ((_isKicking) && (OnStop.AddSeconds(10) > DateTime.Now)) Thread.Sleep(100); if (_isKicking) { _thread.Abort(); _isKicking = false; return _thread.Join(2000); } return !_isKicking; } private void ThreadFunction() { // Send the time of the Feanor client to the server on startup try { if (!_Server.WriteDatetime(Time.UTC) || !_Server.WriteSensors()) _status = ChamberStatus.NoConn; } catch { _status = ChamberStatus.NoConn; } Results resultBiz = new Results(); _lastKick = DateTime.Now; while (_status != ChamberStatus.AbortRequested && ((Thread.CurrentThread.ThreadState & System.Threading.ThreadState.AbortRequested) == 0)) { // Try to read from server every _lastKick milliseconds if (DateTime.Now > _lastKick.AddMilliseconds(interval)) // was: _KickIntervalms is het /contenttoclient interval! (nu 1 min!) { interval = _KickIntervalms; _lastKick = DateTime.Now; if (_Server.Read()) { _LastHTTP = DateTime.Now; _status = ChamberStatus.Running; if (_Server.Results.Count > 0) { if(_Server.Chamber.Humidity == true) { resultBiz.Add(_Server.Results); // stuurt de resultaten naar de SQL DB (Results) } else { resultBiz.AddOudeHal(_Server.Results); // stuurt de resultaten naar de SQL DB (Results) } _LastDBWrite = DateTime.Now; } if (DateTime.Now > _LastDBWrite.AddSeconds(_Chamber.Interval * 2)) _status = ChamberStatus.Idle; } else _status = ChamberStatus.NoConn; } // It might be interesting to periodically update the calibration and sensor lists in the server. // It might be interesting to periodically update the calibration and sensor lists in the server. // _Server.SetSensorsAndCalibrations(); _isKicking = true; Thread.Sleep(250); } _isKicking = false; _status = ChamberStatus.Aborted; } } }