public virtual bool LocallySynchronizedSubscribe(bool compactFormat, int framesPerSecond, double lagTime, double leadTime, string filterExpression, string dataChannel = null, bool useLocalClockAsRealTime = false, bool ignoreBadTimestamps = false, bool allowSortsByArrival = true, long timeResolution = Ticks.PerMillisecond, bool allowPreemptivePublishing = true, DownsamplingMethod downsamplingMethod = DownsamplingMethod.LastReceived, string startTime = null, string stopTime = null, string constraintParameters = null, int processingInterval = -1, string waitHandleNames = null, int waitHandleTimeout = 0) { // Dispose of any previously established local concentrator DisposeLocalConcentrator(); // Establish a local concentrator to synchronize received measurements m_localConcentrator = new LocalConcentrator(this); m_localConcentrator.ProcessException += m_localConcentrator_ProcessException; m_localConcentrator.FramesPerSecond = framesPerSecond; m_localConcentrator.LagTime = lagTime; m_localConcentrator.LeadTime = leadTime; m_localConcentrator.UseLocalClockAsRealTime = useLocalClockAsRealTime; m_localConcentrator.IgnoreBadTimestamps = ignoreBadTimestamps; m_localConcentrator.AllowSortsByArrival = allowSortsByArrival; m_localConcentrator.TimeResolution = timeResolution; m_localConcentrator.AllowPreemptivePublishing = allowPreemptivePublishing; m_localConcentrator.DownsamplingMethod = downsamplingMethod; m_localConcentrator.UsePrecisionTimer = false; // Parse time constraints, if defined DateTime startTimeConstraint = !string.IsNullOrWhiteSpace(startTime) ? ParseTimeTag(startTime) : DateTime.MinValue; DateTime stopTimeConstraint = !string.IsNullOrWhiteSpace(stopTime) ? ParseTimeTag(stopTime) : DateTime.MaxValue; // When processing historical data, timestamps should not be evaluated for reasonability if (startTimeConstraint != DateTime.MinValue || stopTimeConstraint != DateTime.MaxValue) { m_localConcentrator.PerformTimestampReasonabilityCheck = false; m_localConcentrator.LeadTime = double.MaxValue; } // Assign alternate processing interval, if defined if (processingInterval != -1) m_localConcentrator.ProcessingInterval = processingInterval; // Initiate unsynchronized subscribe StringBuilder connectionString = new StringBuilder(); AssemblyInfo assemblyInfo = AssemblyInfo.ExecutingAssembly; connectionString.AppendFormat("trackLatestMeasurements={0}; ", false); connectionString.AppendFormat("inputMeasurementKeys={{{0}}}; ", filterExpression.ToNonNullString()); connectionString.AppendFormat("dataChannel={{{0}}}; ", dataChannel.ToNonNullString()); connectionString.AppendFormat("includeTime={0}; ", true); connectionString.AppendFormat("lagTime={0}; ", 10.0D); connectionString.AppendFormat("leadTime={0}; ", 5.0D); connectionString.AppendFormat("useLocalClockAsRealTime={0}; ", false); connectionString.AppendFormat("startTimeConstraint={0}; ", startTime.ToNonNullString()); connectionString.AppendFormat("stopTimeConstraint={0}; ", stopTime.ToNonNullString()); connectionString.AppendFormat("timeConstraintParameters={0}; ", constraintParameters.ToNonNullString()); connectionString.AppendFormat("processingInterval={0}; ", processingInterval); connectionString.AppendFormat("useMillisecondResolution={0}; ", m_useMillisecondResolution); connectionString.AppendFormat("assemblyInfo={{source={0}; version={1}.{2}.{3}; buildDate={4}}}", assemblyInfo.Name, assemblyInfo.Version.Major, assemblyInfo.Version.Minor, assemblyInfo.Version.Build, assemblyInfo.BuildDate.ToString("yyyy-MM-dd HH:mm:ss")); if (!string.IsNullOrWhiteSpace(waitHandleNames)) { connectionString.AppendFormat("; waitHandleNames={0}", waitHandleNames); connectionString.AppendFormat("; waitHandleTimeout={0}", waitHandleTimeout); } // Start subscription process if (Subscribe(false, compactFormat, connectionString.ToString())) { // If subscription succeeds, start local concentrator m_localConcentrator.Start(); return true; } return false; }
/// <summary> /// Subscribes (or re-subscribes) to a data publisher for a synchronized set of data points. /// </summary> /// <param name="info">Configuration object that defines the subscription.</param> /// <returns><c>true</c> if subscribe transmission was successful; otherwise <c>false</c>.</returns> public bool SynchronizedSubscribe(SynchronizedSubscriptionInfo info) { StringBuilder connectionString = new StringBuilder(); AssemblyInfo assemblyInfo = AssemblyInfo.ExecutingAssembly; // Dispose of any previously established local concentrator DisposeLocalConcentrator(); if (info.RemotelySynchronized) { connectionString.AppendFormat("framesPerSecond={0};", info.FramesPerSecond); connectionString.AppendFormat("lagTime={0};", info.LagTime); connectionString.AppendFormat("leadTime={0};", info.LeadTime); connectionString.AppendFormat("includeTime=false;"); connectionString.AppendFormat("useLocalClockAsRealTime={0};", info.UseLocalClockAsRealTime); connectionString.AppendFormat("ignoreBadTimestamps={0};", info.IgnoreBadTimestamps); connectionString.AppendFormat("allowSortsByArrival={0};", info.AllowSortsByArrival); connectionString.AppendFormat("timeResolution={0};", info.TimeResolution); connectionString.AppendFormat("allowPreemptivePublishing={0};", info.AllowPreemptivePublishing); connectionString.AppendFormat("requestNaNValueFilter={0};", info.RequestNaNValueFilter); connectionString.AppendFormat("downsamplingMethod={0};", info.DownsamplingMethod); connectionString.AppendFormat("processingInterval={0};", info.ProcessingInterval); connectionString.AppendFormat("assemblyInfo={{source={0};version={1}.{2}.{3};buildDate={4}}};", assemblyInfo.Name, assemblyInfo.Version.Major, assemblyInfo.Version.Minor, assemblyInfo.Version.Build, assemblyInfo.BuildDate.ToString("yyyy-MM-dd HH:mm:ss")); if (!string.IsNullOrWhiteSpace(info.FilterExpression)) connectionString.AppendFormat("inputMeasurementKeys={{{0}}};", info.FilterExpression); if (info.UdpDataChannel) connectionString.AppendFormat("dataChannel={{localport={0}}};", info.DataChannelLocalPort); if (!string.IsNullOrWhiteSpace(info.StartTime)) connectionString.AppendFormat("startTimeConstraint={0};", info.StartTime); if (!string.IsNullOrWhiteSpace(info.StopTime)) connectionString.AppendFormat("stopTimeConstraint={0};", info.StopTime); if (!string.IsNullOrWhiteSpace(info.ConstraintParameters)) connectionString.AppendFormat("timeConstraintParameters={0};", info.ConstraintParameters); if (!string.IsNullOrWhiteSpace(info.ExtraConnectionStringParameters)) connectionString.AppendFormat("{0};", info.ExtraConnectionStringParameters); return Subscribe(true, info.UseCompactMeasurementFormat, connectionString.ToString()); } // Locally concentrated subscription simply uses an unsynchronized subscription and concentrates the // measurements on the subscriber side if (Subscribe(FromLocallySynchronizedInfo(info))) { // Establish a local concentrator to synchronize received measurements LocalConcentrator localConcentrator = new LocalConcentrator(this); localConcentrator.ProcessException += m_localConcentrator_ProcessException; localConcentrator.FramesPerSecond = info.FramesPerSecond; localConcentrator.LagTime = info.LagTime; localConcentrator.LeadTime = info.LeadTime; localConcentrator.UseLocalClockAsRealTime = info.UseLocalClockAsRealTime; localConcentrator.IgnoreBadTimestamps = info.IgnoreBadTimestamps; localConcentrator.AllowSortsByArrival = info.AllowSortsByArrival; localConcentrator.TimeResolution = info.TimeResolution; localConcentrator.AllowPreemptivePublishing = info.AllowPreemptivePublishing; localConcentrator.DownsamplingMethod = info.DownsamplingMethod; localConcentrator.UsePrecisionTimer = false; // Parse time constraints, if defined DateTime startTimeConstraint = !string.IsNullOrWhiteSpace(info.StartTime) ? ParseTimeTag(info.StartTime) : DateTime.MinValue; DateTime stopTimeConstraint = !string.IsNullOrWhiteSpace(info.StopTime) ? ParseTimeTag(info.StopTime) : DateTime.MaxValue; // When processing historical data, timestamps should not be evaluated for reasonability if (startTimeConstraint != DateTime.MinValue || stopTimeConstraint != DateTime.MaxValue) { localConcentrator.PerformTimestampReasonabilityCheck = false; localConcentrator.LeadTime = double.MaxValue; } // Assign alternate processing interval, if defined if (info.ProcessingInterval != -1) localConcentrator.ProcessingInterval = info.ProcessingInterval; // Start local concentrator localConcentrator.Start(); // Move concentrator to member variable Interlocked.Exchange(ref m_localConcentrator, localConcentrator); return true; } return false; }