History

TimeSeriesPlatformLibrary: (1) Improved operation of SubscriberInstance, (2) Updated function signatures for DataSubscriber to always include subscriber reference since callbacks require a static function, this allows "instance" implementations to have access to source subscriber.

J. Ritchie Carroll committed 8 years ago

Commit ddde4ba1 parent 24ecf3a7 files · +336 −230Browse files

Showing the changes to Source/Libraries/TimeSeriesPlatformLibrary/Samples/SubscriberInstance.cpp (1 of 7 files). Show all

Unified · Split

Source/Libraries/TimeSeriesPlatformLibrary/Samples/SubscriberInstance.cpp+211−134
@@ -21,22 +21,21 @@ · 20 unmodified lines
21//21//
22//******************************************************************************************************22//******************************************************************************************************
23 23
24#include <functional>
25
24#include "SubscriberInstance.h"26#include "SubscriberInstance.h"
25#include "../Transport/Constants.h"27#include "../Transport/Constants.h"
26 28
27SubscriberInstance::SubscriberInstance() :29SubscriberInstance::SubscriberInstance() :
28 m_hostname("localhost"),30 m_hostname("localhost"),
29 m_port(6165),31 m_port(6165),
30 m_udpPort(0),32 m_udpPort(0),
31 m_filterExpression("FILTER ActiveMeasurements WHERE Protocol = 'GatewayTransport'"),33 m_filterExpression(SubscribeAllExpression),
32 m_startTime(""),34 m_startTime(""),
33 m_stopTime(""),35 m_stopTime("")
34 m_statusMessageCallback(0),
35 m_errorMessageCallback(0),
36 m_metadataCallback(0),
37 m_newMeasurementsCallback(0),
38 m_historicalReadCompleteCallback(0)
39{36{
37 // Reference this SubscriberInstance in DataSubsciber user data
38 m_subscriber.SetUserData(this);
40}39}
41 40
42SubscriberInstance::~SubscriberInstance()41SubscriberInstance::~SubscriberInstance()
@@ -45,186 +44,264 @@ SubscriberInstance::~SubscriberInstance() · 2 unmodified lines
45 44
46// public functions45// public functions
47 46
48void SubscriberInstance::RegisterStatusMessageCallback(MessageCallback statusMessageCallback)47void SubscriberInstance::Initialize(std::string hostname, gsfts::uint16_t port, gsfts::uint16_t udpPort)
49{48{
50 m_statusMessageCallback = statusMessageCallback;49 m_hostname = hostname;
50 m_port = port;
51 m_udpPort = udpPort;
51}52}
52 53
53void SubscriberInstance::RegisterErrorMessageCallback(MessageCallback errorMessageCallback)54void SubscriberInstance::EstablishHistoricalRead(std::string startTime, std::string stopTime)
54{55{
55 m_errorMessageCallback = errorMessageCallback;56 m_startTime = startTime;
57 m_stopTime = stopTime;
56}58}
57 59
58void SubscriberInstance::RegisterMetadataCallback(MetadataCallback metadataCallback)60void SubscriberInstance::SetFilterExpression(std::string filterExpression)
59{61{
60 m_metadataCallback = metadataCallback;62 m_filterExpression = filterExpression;
61}63}
62 64
63void SubscriberInstance::RegisterNewMeasurementsCallback(NewMeasurementsCallback processMeasurementsCallback)65void SubscriberInstance::Connect()
64{66{
65 m_newMeasurementsCallback = processMeasurementsCallback;67 // The connector is declared here because it
68 // is only needed for the initial connection
69 tst::SubscriberConnector connector;
70
71 // Set up helper objects (derived classes can override behavior)
72 connector = CreateSubscriberConnector();
73 m_info = CreateSubscriptionInfo();
74
75 // Register callbacks
76 m_subscriber.RegisterStatusMessageCallback(&HandleStatusMessage);
77 m_subscriber.RegisterErrorMessageCallback(&HandleErrorMessage);
78
79 if (!m_startTime.empty() && !m_stopTime.empty())
80 {
81 m_subscriber.RegisterProcessingCompleteCallback(&HandleProcessingComplete);
82 m_info.StartTime = m_startTime;
83 m_info.StopTime = m_stopTime;
84 }
85
86 if (m_udpPort > 0)
87 {
88 m_info.UdpDataChannel = true;
89 m_info.DataChannelLocalPort = m_udpPort;
90 }
91
92 m_subscriber.RegisterMetadataCallback(this->HandleMetadata);
93 m_subscriber.RegisterConfigurationChangedCallback(this->HandleConfigurationChanged);
94
95 // Connect and subscribe to publisher
96 if (connector.Connect(m_subscriber))
97 {
98 // Request metadata upon successful connection, after metadata is handled
99 // the SubscriberInstance will then subscribe to the desired data
100 m_subscriber.SendServerCommand(tst::ServerCommand::MetadataRefresh);
101 }
102 else
103 {
104 ErrorMessage("All connection attempts failed");
105 }
66}106}
67 107
68void SubscriberInstance::Initialize(std::string hostname, gsfts::uint16_t port, gsfts::uint16_t udpPort)108void SubscriberInstance::Disconnect()
69{109{
70 m_hostname = hostname;110 m_subscriber.Disconnect();
71 m_port = port;
72 m_udpPort = udpPort;
73}111}
74 112
75void SubscriberInstance::EstablishHistoricalRead(std::string startTime, std::string stopTime)113void SubscriberInstance::SetHistoricalReplayInterval(int32_t replayInterval)
76{114{
77 m_startTime = startTime;115 if (m_subscriber.IsSubscribed())
78 m_stopTime = stopTime;116 {
117 replayInterval = m_endianConverter.ConvertBigEndian(replayInterval);
118 m_subscriber.SendServerCommand(tst::ServerCommand::UpdateProcessingInterval, (gsfts::uint8_t*)&replayInterval, 0, 4);
119 }
79}120}
80 121
81void SubscriberInstance::Connect()122void* SubscriberInstance::GetUserData() const
82{123{
83 // The connector is declared here because it124 return m_userData;
84 // is only needed for the initial connection
85 tst::SubscriberConnector connector;
86
87 // Set up helper objects
88 connector = CreateSubscriberConnector(m_hostname, m_port);
89 m_info = CreateSubscriptionInfo();
90
91 // Register callbacks
92 if (m_statusMessageCallback)
93 m_subscriber.RegisterStatusMessageCallback(m_statusMessageCallback);
94
95 if (m_errorMessageCallback)
96 m_subscriber.RegisterErrorMessageCallback(m_errorMessageCallback);
97
98 if (!m_startTime.empty() && !m_stopTime.empty())
99 {
100 m_subscriber.RegisterProcessingCompleteCallback(this->HandleProcessComplete);
101 m_info.StartTime = m_startTime;
102 m_info.StopTime = m_stopTime;
103 }
104
105 if (m_udpPort > 0)
106 {
107 m_info.UdpDataChannel = true;
108 m_info.DataChannelLocalPort = m_udpPort;
109 }
110
111 m_subscriber.RegisterMetadataCallback(this->HandleMetadata);
112 m_subscriber.RegisterConfigurationChangedCallback(this->HandleConfigurationChanged);
113
114 // Connect and subscribe to publisher
115 if (connector.Connect(m_subscriber))
116 {
117 // Request metadata upon successful connection, after metadata is handled
118 // the SubscriberInstance will then subscribe to the desired data
119 m_subscriber.SendServerCommand(tst::ServerCommand::MetadataRefresh);
120 }
121 else
122 {
123 if (m_errorMessageCallback)
124 m_errorMessageCallback("All connection attempts failed");
125 }
126}125}
127 126
128void SubscriberInstance::Disconnect()127void SubscriberInstance::SetUserData(void* userData)
129{128{
130 m_subscriber.Disconnect();129 m_userData = userData;
131}130}
132 131
133void SubscriberInstance::SetHistoricalReplayInterval(int32_t replayInterval)132bool SubscriberInstance::IsMetadataCompressed() const
134{133{
135 if (m_subscriber.IsSubscribed())134 return m_subscriber.IsMetadataCompressed();
136 {
137 replayInterval = m_endianConverter.ConvertBigEndian(replayInterval);
138 m_subscriber.SendServerCommand(tst::ServerCommand::UpdateProcessingInterval, (gsfts::uint8_t*)&replayInterval, 0, 4);
139 }
140}135}
141 136
142// private functions137void SubscriberInstance::SetMetadataCompressed(bool compressed)
138{
139 m_subscriber.SetMetadataCompressed(compressed);
140}
143 141
144tst::SubscriberConnector SubscriberInstance::CreateSubscriberConnector(std::string hostname, gsfts::uint16_t port)142long SubscriberInstance::GetTotalCommandChannelBytesReceived() const
145{143{
146 // SubscriberConnector is another helper object which allows the144 return m_subscriber.GetTotalCommandChannelBytesReceived();
147 // user to modify settings for auto-reconnects and retry cycles.145}
148 tst::SubscriberConnector connector;
149 146
150 if (m_errorMessageCallback)147long SubscriberInstance::GetTotalDataChannelBytesReceived() const
151 connector.RegisterErrorMessageCallback(m_errorMessageCallback);148{
149 return m_subscriber.GetTotalDataChannelBytesReceived();
150}
152 151
153 connector.RegisterReconnectCallback(this->HandleResubscribe);152long SubscriberInstance::GetTotalMeasurementsReceived() const
153{
154 return m_subscriber.GetTotalMeasurementsReceived();
155}
154 156
155 connector.SetHostname(hostname);157bool SubscriberInstance::IsConnected() const
156 connector.SetPort(port);158{
157 connector.SetMaxRetries(5);159 return m_subscriber.IsConnected();
158 connector.SetRetryInterval(1000);160}
159 connector.SetAutoReconnect(true);
160 161
161 return connector;162bool SubscriberInstance::IsSubscribed() const
163{
164 return m_subscriber.IsSubscribed();
165}
166
167// protected functions
168
169tst::SubscriberConnector SubscriberInstance::CreateSubscriberConnector()
170{
171 // SubscriberConnector is another helper object which allows the
172 // user to modify settings for auto-reconnects and retry cycles.
173 tst::SubscriberConnector connector;
174
175 // Register callbacks
176 connector.RegisterErrorMessageCallback(&HandleErrorMessage);
177 connector.RegisterReconnectCallback(&HandleResubscribe);
178
179 connector.SetHostname(m_hostname);
180 connector.SetPort(m_port);
181 connector.SetMaxRetries(-1);
182 connector.SetRetryInterval(5000);
183 connector.SetAutoReconnect(true);
184
185 return connector;
162}186}
163 187
164tst::SubscriptionInfo SubscriberInstance::CreateSubscriptionInfo()188tst::SubscriptionInfo SubscriberInstance::CreateSubscriptionInfo()
165{189{
166 // SubscriptionInfo is a helper object which allows the user190 // SubscriptionInfo is a helper object which allows the user
167 // to set up their subscription and reuse subscription settings.191 // to set up their subscription and reuse subscription settings.
168 tst::SubscriptionInfo info;192 tst::SubscriptionInfo info;
169 193
170 // Define desired filter expression194 // Define desired filter expression
171 info.FilterExpression = m_filterExpression;195 info.FilterExpression = m_filterExpression;
172 196
173 // Establish user new measurements call back (if defined)197 // Establish user new measurements call back (if defined)
174 if (m_newMeasurementsCallback)198 info.NewMeasurementsCallback = &HandleNewMeasurements;
175 info.NewMeasurementsCallback = m_newMeasurementsCallback;
176 199
177 // To set up a remotely synchronized subscription, set this flag200 // To set up a remotely synchronized subscription, set this flag
178 // to true and add the framesPerSecond parameter to the201 // to true and add the framesPerSecond parameter to the
179 // ExtraConnectionStringParameters. Additionally, the following202 // ExtraConnectionStringParameters. Additionally, the following
180 // example demonstrates the use of some other useful parameters203 // example demonstrates the use of some other useful parameters
181 // when setting up remotely synchronized subscriptions.204 // when setting up remotely synchronized subscriptions.
182 //205 //
183 //info.RemotelySynchronized = true;206 //info.RemotelySynchronized = true;
184 //info.ExtraConnectionStringParameters = "framesPerSecond=30;timeResolution=10000;downsamplingMethod=Closest";207 //info.ExtraConnectionStringParameters = "framesPerSecond=30;timeResolution=10000;downsamplingMethod=Closest";
185 208
186 info.RemotelySynchronized = false;209 info.RemotelySynchronized = false;
187 info.Throttled = false;210 info.Throttled = false;
188 211
189 info.UdpDataChannel = false;212 info.UdpDataChannel = false;
190 213
191 info.IncludeTime = true;214 info.IncludeTime = true;
192 info.LagTime = 3.0;215 info.LagTime = 3.0;
193 info.LeadTime = 1.0;216 info.LeadTime = 1.0;
194 info.UseLocalClockAsRealTime = false;217 info.UseLocalClockAsRealTime = false;
195 info.UseMillisecondResolution = true;218 info.UseMillisecondResolution = true;
196 219
197 return info;220 return info;
198}221}
199 222
200// Callback that is called when the subscriber auto-reconnects223void SubscriberInstance::ConnectionTerminated()
224{
225}
226
227void SubscriberInstance::StatusMessage(std::string message)
228{
229 std::cout << message << std::endl << std::endl;
230}
231
232void SubscriberInstance::ErrorMessage(std::string message)
233{
234 std::cerr << message << std::endl << std::endl;
235}
236
237void SubscriberInstance::ReceivedMetadata(std::vector<uint8_t> payload)
238{
239}
240
241void SubscriberInstance::ReceivedNewMeasurements(std::vector<gsfts::Measurement> measurements)
242{
243}
244
245void SubscriberInstance::HistoricalReadComplete()
246{
247}
248
249// private functions
250
251// The following member methods are defined as static so they
252// can be used as callback registrations for DataSubscriber
253
201void SubscriberInstance::HandleResubscribe(tst::DataSubscriber* source)254void SubscriberInstance::HandleResubscribe(tst::DataSubscriber* source)
202{255{
203 if (source->IsConnected())256 if (source->IsConnected())
204 source->Subscribe(m_info);257 source->Subscribe(source->GetCurrentSubscription());
205}258}
206 259
207void SubscriberInstance::HandleMetadata(std::vector<uint8_t> payload)260void SubscriberInstance::HandleStatusMessage(tst::DataSubscriber* source, std::string message)
208{261{
209 // Call user defined handle meta-data function262 SubscriberInstance* instance = (SubscriberInstance*)source->GetUserData();
210 if (m_metadataCallback)263 instance->StatusMessage(message);
211 m_metadataCallback(payload);264}
212 265
213 // Start subscription after successful meta-data parse266void SubscriberInstance::HandleErrorMessage(tst::DataSubscriber* source, std::string message)
214 m_subscriber.Subscribe(m_info);267{
268 SubscriberInstance* instance = (SubscriberInstance*)source->GetUserData();
269 instance->ErrorMessage(message);
215}270}
216 271
217void SubscriberInstance::HandleConfigurationChanged()272void SubscriberInstance::HandleConnectionTerminated(tst::DataSubscriber* source)
218{273{
219 // When publisher configuration has changed, request updated metadata274 SubscriberInstance* instance = (SubscriberInstance*)source->GetUserData();
220 m_subscriber.SendServerCommand(tst::ServerCommand::MetadataRefresh);275 instance->ConnectionTerminated();
221}276}
222 277
223void SubscriberInstance::HandleProcessComplete(std::string message)278void SubscriberInstance::HandleMetadata(tst::DataSubscriber* source, std::vector<uint8_t> payload)
224{279{
225 if (m_statusMessageCallback)280 SubscriberInstance* instance = (SubscriberInstance*)source->GetUserData();
226 m_statusMessageCallback(message);281
282 // Call virtual method to handle metadata payload
283 instance->ReceivedMetadata(payload);
284
285 // Start subscription after successful user meta-data handling
286 source->Subscribe(instance->m_info);
287}
227 288
228 if (m_historicalReadCompleteCallback)289void SubscriberInstance::HandleNewMeasurements(tst::DataSubscriber* source, std::vector<gsfts::Measurement> measurements)
229 m_historicalReadCompleteCallback();290{
291 SubscriberInstance* instance = (SubscriberInstance*)source->GetUserData();
292 instance->ReceivedNewMeasurements(measurements);
293}
294
295void SubscriberInstance::HandleConfigurationChanged(tst::DataSubscriber* source)
296{
297 // When publisher configuration has changed, request updated metadata
298 source->SendServerCommand(tst::ServerCommand::MetadataRefresh);
299}
300
301void SubscriberInstance::HandleProcessingComplete(tst::DataSubscriber* source, std::string message)
302{
303 SubscriberInstance* instance = (SubscriberInstance*)source->GetUserData();
304
305 instance->StatusMessage(message);
306 instance->HistoricalReadComplete();
230}307}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t