/// <summary> /// Iterate through the current list of subscribed clients and invoke their HandleParameters event. /// </summary> /// <param name="paras">The ReefANgel parameters to send to individual clients</param> public void SendParams(ReefAngelParams paras) { ThreadPool.QueueUserWorkItem ( delegate { lock (clients) { List<Guid> disconnectedClientGuids = new List<Guid>(); foreach (KeyValuePair<Guid, IReefAngelCallback> client in clients) { try { client.Value.HandleParams(paras); } catch (Exception) { // There is a number of reasons an exception can occur here. // The server might not be able to connect to client b/c of network error, // early client terminiation w/out being able to unsubscribe first or comms object is killed. // No matter the case - mark the client key for removal. disconnectedClientGuids.Add(client.Key); } } foreach (Guid clientGuid in disconnectedClientGuids) { clients.Remove(clientGuid); } } } ); }
/// <summary> /// Parse the XML data sent from ReefAngel Controller and build a ReefAngelParams object that will be sent to individual subscribers. /// </summary> /// <param name="xml">The Received XML Data</param> /// <returns>The Current Parameter values from the controller as a ReefAngelParam object.</returns> private ReefAngelParams GenerateCurrentParams(string xml) { try { rdr = new StringReader(xml); XDocument xdoc = XDocument.Load(rdr, LoadOptions.None); XElement root = xdoc.Element("RA"); currentParams = new ReefAngelParams(); currentParams.ParamTime = DateTime.Now; //TODO: For simplicity I use the systems date/time. However in the future this value should probably come from controller for consistency. currentParams.Temp1 = FormatTemp(root.Element("T1").Value.ToString()); currentParams.Temp2 = FormatTemp(root.Element("T2").Value.ToString()); currentParams.Temp3 = FormatTemp(root.Element("T3").Value.ToString()); currentParams.PH = FormatPH(root.Element("PH").Value.ToString()); BuildRelayStatuses(ToBinary(int.Parse(root.Element("R").Value.ToString())), ToBinary(int.Parse(root.Element("RON").Value.ToString())), ToBinary(int.Parse(root.Element("ROFF").Value.ToString()))); return currentParams; } catch (Exception ex) { // For some reason, controller will sometimes send partial data and incomplete xml causing xmlparse to fail. Ignore it for now and send null object. //TODO: Hanlde the correct XMLParse Exception instead of generic Exception. Log exceptions. currentParams = null; return currentParams; } }