StreamLink can calculate the clock offset between Liberator and StreamLink, the one-way heartbeat message latency between Liberator and StreamLink, and the latency of the records it receives from Liberator. StreamLink stores the results of these calculations and makes them available through the StreamLink API.
The clock offset calculation can be enabled or disabled, but must be enabled if you want StreamLink to calculate heartbeat message or record latency, as it is used in all latency calculations.
Related Documents
StreamLink Configuration XML Reference: Describes the XML-based tags and attributes you can use to configure StreamLink applications.
Clock Offset
The following parameters configure the sync messages that determine when clock offset is calculated:
- SyncSize (default 12) - The number of sync messages that are used in the clock offset calculation.
-
SyncInitialSpacing (default 500) - the initial time in milliseconds between successive sync messages (until the first
SyncSize
messages have been sent). -
SyncSpacing (default 5000) - the time in milliseconds between successive sync messages (after the first
SyncSize
messages have been sent). Set to 0 to disable sync messages. If sync messages are disabled, the clock offset is not calculated.
The sync message parameters can be specified using the <RttpService>
tag in the application XML configuration file, or in code as attributes of an IConnectionConfiguration instance:
Configuring sync messages in XML
<RttpService Name="Example RTTP Service" SyncSpacing="2000" SyncInitialSpacing="200" SyncSize="10">
Configuring sync messages in StreamLink code
IStreamLinkConfiguration config = SimpleConfiguration.CreateType1Connection("localhost", 15000);
IConnectionConfiguration connectionConfiguration = config.ConnectionConfiguration;
connectionConfiguration.SyncSpacing = 2000;
connectionConfiguration.SyncInitialSpacing = 200;
connectionConfiguration.SyncSize = 10;
When StreamLink is configured to calculate clock offset, it periodically sends time stamped sync messages to Liberator.
Liberator adds its own timestamp to each sync message it receives, and immediately returns the sync message to StreamLink.
StreamLink uses the sync message with the quickest round trip time from the last SyncSize
messages to calculate the clock offset
between Liberator and StreamLink. Because the value of SyncInitialSpacing
is less than the value of SyncSpacing
, the time it takes
to send and receive the first SyncSize
messages is reduced.
You can retrieve the result of the latest clock offset calculation using the Statistics property of an IStreamLinkProvider.
IStreamLinkProvider provider = myStreamLink.StreamLinkProvider;
IStatistics statistics = provider.Statistics;
long clockOffset = statistics.ClockOffset;
Heartbeat Latency
Liberator 5.1 and above can be requested to send heartbeat messages that StreamLink uses to calculate the average and latest heartbeat message latency between Liberator and StreamLink. Note that heartbeat message latency can only be calculated if the clock offset between Liberator and StreamLink is available (see Clock Offset above).
The following parameter determines how often Liberator sends a heartbeat message:
- HeartbeatInterval (default 5000) - The time in milliseconds between heartbeat messages. Set to 0 to disable heartbeat messages. If heartbeat messages are disabled, heartbeat latency is not calculated.
The heartbeat message interval can be specified using the <RttpService>
tag in the application XML configuration file, or in code as attributes of an IConnectionConfiguration instance:
Configuring the heartbeat in XML
<RttpService Name="Example RTTP Service" HeartbeatInterval="4000">
Configuring the heartbeat in StreamLink code
IStreamLinkConfiguration config = SimpleConfiguration.CreateType1Connection("localhost", 15000);
IConnectionConfiguration connectionConfiguration = config.ConnectionConfiguration;
connectionConfiguration.HeartbeatInterval = 4000;
You can retrieve the calculated latency of heartbeat messages using the Statistics property of an IStreamLinkProvider:
IStreamLinkProvider provider = myStreamLink.StreamLinkProvider;
IStatistics statistics = provider.Statistics;
long latestLatency = statistics.Latency;
long averageLatency = statistics.AverageLatency;
Note that StreamLink uses the arithmetic average of the last SyncSize
latency values to calculate the average heartbeat latency (see Clock Offset above for a description of SyncSize
).
Statistics Listener
You can implement and register a Caplin.StreamLink.IStatisticsListener that is notified when the statistics object containing the clock offset and heartbeat latency is updated:
public class ExampleStatisticsListener: IStatisticsListener
{
public void StatisticsUpdated(IStatisticsEvent ev)
{
String msg = String.Format("Received statistics update {0}", ev.Statistics.ToString());
this.Logger.Log(SourceLevels.Information, "Example", msg);
}
}
IStatisticsListener listener = new ExampleStatisticsListener();
IStreamLinkProvider provider = myStreamLink.StreamLinkProvider;
provider.AddStatisticsListener(listener);
In this example, the statistics listener ExampleStatisticsListener
simply logs the latest statistics as a string.
Record Latency
If StreamLink is configured to calculate the clock offset between Liberator and StreamLink, and if the records received from Liberator contain a timestamp field, the getLatency(string timeStampField) method of the IRecordEvent interface can be used to obtain the latency of received records.
public void RecordUpdated(ISubscription subscription, IRecordEvent ev)
{
long latency = ev.getLatency("dTimeStamp");
this.Logger.Log(SourceLevels.Information, "Example", "Latency= " + latency);
}
In this example, the custom RecordUpdated()
method simply logs the record latency as a string.
The latency of type 2 and type 3 records can be retrieved in a similar manner using the IRecordType2Event and IRecordType3Event interfaces.
Note that you can configure Liberator to add a timestamp field to every record that it sends, by adding the following line to the Liberator configuration file rttpd.conf
:
timestamp-field dTimeStamp
For further information, see the document Caplin Liberator Administration Guide.