/// <summary> /// Encodes a high-frequency based Date and Time value to XML. /// </summary> /// <param name="Timestamp">Timestamp</param> /// <param name="Xml">XML output</param> public static void Encode(DateTimeHF Timestamp, StringBuilder Xml) { Xml.Append(Timestamp.Year.ToString("D4")); Xml.Append('-'); Xml.Append(Timestamp.Month.ToString("D2")); Xml.Append('-'); Xml.Append(Timestamp.Day.ToString("D2")); Xml.Append('T'); Xml.Append(Timestamp.Hour.ToString("D2")); Xml.Append(':'); Xml.Append(Timestamp.Minute.ToString("D2")); Xml.Append(':'); Xml.Append(Timestamp.Second.ToString("D2")); Xml.Append('.'); Xml.Append(Timestamp.Millisecond.ToString("D3")); Xml.Append(Timestamp.Microsecond.ToString("D3")); Xml.Append(Timestamp.Nanosecond100.ToString("D1")); Xml.Append('Z'); }
private void Clock(object Sender, IqEventArgs e) { DateTimeHF Now = SynchronizationClient.Now; StringBuilder Xml = new StringBuilder(); Xml.Append("<resp xmlns='"); Xml.Append(NamespaceSynchronization); if (Now.Ticks.HasValue) { Xml.Append("' hf='"); Xml.Append(Now.Ticks.Value.ToString()); Xml.Append("' freq='"); Xml.Append(Stopwatch.Frequency.ToString()); } Xml.Append("'>"); Encode(Now, Xml); Xml.Append("</resp>"); e.IqResult(Xml.ToString()); }
/// <summary> /// Measures the difference between the client clock and the clock of a clock source. /// </summary> /// <param name="ClockSourceJID">JID of clock source.</param> /// <param name="Callback">Callback method</param> /// <param name="State">State object to pass on to callback method.</param> public void MeasureClockDifference(string ClockSourceJID, SynchronizationEventHandler Callback, object State) { DateTimeHF ClientTime1 = SynchronizationClient.Now; this.client.SendIqGet(ClockSourceJID, "<req xmlns='" + NamespaceSynchronization + "'/>", (sender, e) => { DateTimeHF ClientTime2 = SynchronizationClient.Now; XmlElement E; long Latency100Ns; long ClockDifference100Ns; long?LatencyHF; long?ClockDifferenceHF; if (e.Ok && (E = e.FirstElement) != null && E.LocalName == "resp" && E.NamespaceURI == NamespaceSynchronization && DateTimeHF.TryParse(E.InnerText, out DateTimeHF ServerTime)) { long dt1 = ServerTime - ClientTime1; long dt2 = ClientTime2 - ServerTime; Latency100Ns = dt1 + dt2; ClockDifference100Ns = dt1 - dt2; if (E.HasAttribute("hf") && long.TryParse(E.GetAttribute("hf"), out long Hf) && E.HasAttribute("freq") && long.TryParse(E.GetAttribute("freq"), out long Freq)) { if (Freq != Stopwatch.Frequency) { double d = Hf; d *= Stopwatch.Frequency; d /= Freq; Hf = (long)(d + 0.5); } dt1 = Hf - ClientTime1.Ticks.Value; dt2 = ClientTime2.Ticks.Value - Hf; LatencyHF = dt1 + dt2; ClockDifferenceHF = dt1 - dt2; } else { LatencyHF = null; ClockDifferenceHF = null; } } else { e.Ok = false; Latency100Ns = 0; ClockDifference100Ns = 0; LatencyHF = null; ClockDifferenceHF = null; } try { Callback?.Invoke(this, new SynchronizationEventArgs(Latency100Ns, ClockDifference100Ns, LatencyHF, ClockDifferenceHF, Stopwatch.Frequency, e)); } catch (Exception ex) { Log.Critical(ex); } return(Task.CompletedTask); }, State); }