Showing the changes to Source/Libraries/TimeSeriesPlatformLibrary/Transport/DataPublisher.cpp (1 of 28 files). Show all
Unified · Split
| @@ -36,24 +36,13 @@ using namespace GSF::FilterExpressions; · 35 unmodified lines | ||
| 36 | 36 | using namespace GSF::TimeSeries; |
| 37 | 37 | using namespace GSF::TimeSeries::Transport; |
| 38 | 38 | |
| 39 | −struct SubscriberConnectionInfo | |
| 40 | −{ | |
| 41 | − const GSF::Guid SubscriberID; | |
| 42 | − const string ConnectionID; | |
| 43 | − | |
| 44 | − SubscriberConnectionInfo(const GSF::Guid& subscriberID, string connectionID) : | |
| 45 | − SubscriberID(subscriberID), | |
| 46 | − ConnectionID(std::move(connectionID)) | |
| 47 | − { | |
| 48 | − } | |
| 49 | −}; | |
| 50 | − | |
| 51 | 39 | DataPublisher::DataPublisher(const TcpEndPoint& endpoint) : |
| 52 | 40 | m_nodeID(NewGuid()), |
| 53 | 41 | m_securityMode(SecurityMode::None), |
| 54 | 42 | m_allowMetadataRefresh(true), |
| 55 | 43 | m_allowNaNValueFilter(true), |
| 56 | 44 | m_forceNaNValueFilter(false), |
| 45 | + m_supportsTemporalSubscriptions(false), | |
| 57 | 46 | m_cipherKeyRotationPeriod(60000), |
| 58 | 47 | m_userData(nullptr), |
| 59 | 48 | m_disposing(false), |
| @@ -116,19 +105,21 @@ void DataPublisher::AcceptConnection(const SubscriberConnectionPtr& connection, · 56 unmodified lines | ||
| 116 | 105 | m_subscriberConnectionsLock.unlock(); |
| 117 | 106 | |
| 118 | 107 | connection->Start(); |
| 119 | − DispatchClientConnected(connection->GetSubscriberID(), connection->GetConnectionID()); | |
| 108 | + DispatchClientConnected(connection); | |
| 120 | 109 | } |
| 121 | 110 | |
| 122 | 111 | StartAccept(); |
| 123 | 112 | } |
| 124 | 113 | |
| 114 | +void DataPublisher::ConnectionTerminated(const SubscriberConnectionPtr& connection) | |
| 115 | +{ | |
| 116 | + DispatchClientDisconnected(connection); | |
| 117 | +} | |
| 118 | + | |
| 125 | 119 | void DataPublisher::RemoveConnection(const SubscriberConnectionPtr& connection) |
| 126 | 120 | { |
| 127 | 121 | m_subscriberConnectionsLock.lock(); |
| 128 | − | |
| 129 | − if (m_subscriberConnections.erase(connection)) | |
| 130 | − DispatchClientDisconnected(connection->GetSubscriberID(), connection->GetConnectionID()); | |
| 131 | − | |
| 122 | + m_subscriberConnections.erase(connection); | |
| 132 | 123 | m_subscriberConnectionsLock.unlock(); |
| 133 | 124 | } |
| 134 | 125 | |
| @@ -169,16 +160,28 @@ void DataPublisher::DispatchErrorMessage(const string& message) · 34 unmodified lines | ||
| 169 | 160 | Dispatch(&ErrorMessageDispatcher, reinterpret_cast<const uint8_t*>(message.c_str()), 0, messageSize); |
| 170 | 161 | } |
| 171 | 162 | |
| 172 | −void DataPublisher::DispatchClientConnected(const GSF::Guid& subscriberID, const string& connectionID) | |
| 163 | +void DataPublisher::DispatchClientConnected(const SubscriberConnectionPtr& connection) | |
| 164 | +{ | |
| 165 | + SubscriberConnection* connectionReference = &*connection; | |
| 166 | + Dispatch(&ClientConnectedDispatcher, reinterpret_cast<uint8_t*>(&connectionReference), 0, sizeof(SubscriberConnection**)); | |
| 167 | +} | |
| 168 | + | |
| 169 | +void DataPublisher::DispatchClientDisconnected(const SubscriberConnectionPtr& connection) | |
| 170 | +{ | |
| 171 | + SubscriberConnection* connectionReference = &*connection; | |
| 172 | + Dispatch(&ClientDisconnectedDispatcher, reinterpret_cast<uint8_t*>(&connectionReference), 0, sizeof(SubscriberConnection**)); | |
| 173 | +} | |
| 174 | + | |
| 175 | +void DataPublisher::DispatchTemporalSubscriptionRequested(const SubscriberConnectionPtr& connection) | |
| 173 | 176 | { |
| 174 | − SubscriberConnectionInfo* data = new SubscriberConnectionInfo(subscriberID, connectionID); | |
| 175 | − Dispatch(&ClientConnectedDispatcher, reinterpret_cast<uint8_t*>(&data), 0, sizeof(SubscriberConnectionInfo**)); | |
| 177 | + SubscriberConnection* connectionReference = &*connection; | |
| 178 | + Dispatch(&TemporalSubscriptionRequestedDispatcher, reinterpret_cast<uint8_t*>(&connectionReference), 0, sizeof(SubscriberConnection**)); | |
| 176 | 179 | } |
| 177 | 180 | |
| 178 | −void DataPublisher::DispatchClientDisconnected(const GSF::Guid& subscriberID, const std::string& connectionID) | |
| 181 | +void DataPublisher::DispatchTemporalProcessingIntervalChangeRequested(const SubscriberConnectionPtr& connection) | |
| 179 | 182 | { |
| 180 | − SubscriberConnectionInfo* data = new SubscriberConnectionInfo(subscriberID, connectionID); | |
| 181 | − Dispatch(&ClientDisconnectedDispatcher, reinterpret_cast<uint8_t*>(&data), 0, sizeof(SubscriberConnectionInfo**)); | |
| 183 | + SubscriberConnection* connectionReference = &*connection; | |
| 184 | + Dispatch(&TemporalProcessingIntervalChangeRequestedDispatcher, reinterpret_cast<uint8_t*>(&connectionReference), 0, sizeof(SubscriberConnection**)); | |
| 182 | 185 | } |
| 183 | 186 | |
| 184 | 187 | // Dispatcher function for status messages. Decodes the message and provides it to the user via the status message callback. |
| @@ -207,32 +210,56 @@ void DataPublisher::ErrorMessageDispatcher(DataPublisher* source, const vector<u · 22 unmodified lines | ||
| 207 | 210 | |
| 208 | 211 | void DataPublisher::ClientConnectedDispatcher(DataPublisher* source, const vector<uint8_t>& buffer) |
| 209 | 212 | { |
| 210 | − SubscriberConnectionInfo* data = *reinterpret_cast<SubscriberConnectionInfo**>(const_cast<uint8_t*>(&buffer[0])); | |
| 213 | + SubscriberConnection* connection = *reinterpret_cast<SubscriberConnection**>(const_cast<uint8_t*>(&buffer[0])); | |
| 211 | 214 | |
| 212 | 215 | if (source != nullptr) |
| 213 | 216 | { |
| 214 | 217 | const SubscriberConnectionCallback clientConnectedCallback = source->m_clientConnectedCallback; |
| 215 | 218 | |
| 216 | 219 | if (clientConnectedCallback != nullptr) |
| 217 | − clientConnectedCallback(source, data->SubscriberID, data->ConnectionID); | |
| 220 | + clientConnectedCallback(source, connection->GetReference()); | |
| 218 | 221 | } |
| 219 | − | |
| 220 | − delete data; | |
| 221 | 222 | } |
| 222 | 223 | |
| 223 | 224 | void DataPublisher::ClientDisconnectedDispatcher(DataPublisher* source, const std::vector<uint8_t>& buffer) |
| 224 | 225 | { |
| 225 | − SubscriberConnectionInfo* data = *reinterpret_cast<SubscriberConnectionInfo**>(const_cast<uint8_t*>(&buffer[0])); | |
| 226 | + SubscriberConnection* connection = *reinterpret_cast<SubscriberConnection**>(const_cast<uint8_t*>(&buffer[0])); | |
| 226 | 227 | |
| 227 | 228 | if (source != nullptr) |
| 228 | 229 | { |
| 229 | 230 | const SubscriberConnectionCallback clientDisconnectedCallback = source->m_clientDisconnectedCallback; |
| 230 | 231 | |
| 231 | 232 | if (clientDisconnectedCallback != nullptr) |
| 232 | − clientDisconnectedCallback(source, data->SubscriberID, data->ConnectionID); | |
| 233 | + clientDisconnectedCallback(source, connection->GetReference()); | |
| 234 | + | |
| 235 | + source->RemoveConnection(connection->GetReference()); | |
| 236 | + } | |
| 237 | +} | |
| 238 | + | |
| 239 | +void DataPublisher::TemporalSubscriptionRequestedDispatcher(DataPublisher* source, const std::vector<uint8_t>& buffer) | |
| 240 | +{ | |
| 241 | + SubscriberConnection* connection = *reinterpret_cast<SubscriberConnection**>(const_cast<uint8_t*>(&buffer[0])); | |
| 242 | + | |
| 243 | + if (source != nullptr) | |
| 244 | + { | |
| 245 | + const SubscriberConnectionCallback temporalSubscriptionRequestedCallback = source->m_temporalSubscriptionRequestedCallback; | |
| 246 | + | |
| 247 | + if (temporalSubscriptionRequestedCallback != nullptr) | |
| 248 | + temporalSubscriptionRequestedCallback(source, connection->GetReference()); | |
| 233 | 249 | } |
| 250 | +} | |
| 251 | + | |
| 252 | +void DataPublisher::TemporalProcessingIntervalChangeRequestedDispatcher(DataPublisher* source, const std::vector<uint8_t>& buffer) | |
| 253 | +{ | |
| 254 | + SubscriberConnection* connection = *reinterpret_cast<SubscriberConnection**>(const_cast<uint8_t*>(&buffer[0])); | |
| 255 | + | |
| 256 | + if (source != nullptr) | |
| 257 | + { | |
| 258 | + const SubscriberConnectionCallback temporalProcessingIntervalChangeRequestedCallback = source->m_temporalProcessingIntervalChangeRequestedCallback; | |
| 234 | 259 | |
| 235 | − delete data; | |
| 260 | + if (temporalProcessingIntervalChangeRequestedCallback != nullptr) | |
| 261 | + temporalProcessingIntervalChangeRequestedCallback(source, connection->GetReference()); | |
| 262 | + } | |
| 236 | 263 | } |
| 237 | 264 | |
| 238 | 265 | int32_t DataPublisher::GetColumnIndex(const GSF::Data::DataTablePtr& table, const std::string& columnName) |
| @@ -683,14 +710,27 @@ vector<MeasurementMetadataPtr> DataPublisher::FilterMetadata(const string& filte · 444 unmodified lines | ||
| 683 | 710 | |
| 684 | 711 | void DataPublisher::PublishMeasurements(const vector<Measurement>& measurements) |
| 685 | 712 | { |
| 686 | − for (const auto& connection : m_subscriberConnections) | |
| 687 | − connection->PublishMeasurements(measurements); | |
| 713 | + vector<MeasurementPtr> measurementPtrs; | |
| 714 | + | |
| 715 | + measurementPtrs.reserve(measurements.size()); | |
| 716 | + | |
| 717 | + for (const auto& measurement : measurements) | |
| 718 | + measurementPtrs.push_back(ToPtr(measurement)); | |
| 719 | + | |
| 720 | + PublishMeasurements(measurementPtrs); | |
| 688 | 721 | } |
| 689 | 722 | |
| 690 | 723 | void DataPublisher::PublishMeasurements(const vector<MeasurementPtr>& measurements) |
| 691 | 724 | { |
| 725 | + m_subscriberConnectionsLock.lock(); | |
| 726 | + | |
| 692 | 727 | for (const auto& connection : m_subscriberConnections) |
| 693 | − connection->PublishMeasurements(measurements); | |
| 728 | + { | |
| 729 | + if (connection->GetIsSubscribed() && !connection->GetIsTemporalSubscription()) | |
| 730 | + connection->PublishMeasurements(measurements); | |
| 731 | + } | |
| 732 | + | |
| 733 | + m_subscriberConnectionsLock.unlock(); | |
| 694 | 734 | } |
| 695 | 735 | |
| 696 | 736 | const GSF::Guid& DataPublisher::GetNodeID() const |
| @@ -743,6 +783,16 @@ void DataPublisher::SetNaNValueFilterForced(bool forced) · 46 unmodified lines | ||
| 743 | 783 | m_forceNaNValueFilter = forced; |
| 744 | 784 | } |
| 745 | 785 | |
| 786 | +bool DataPublisher::GetSupportsTemporalSubscriptions() const | |
| 787 | +{ | |
| 788 | + return m_supportsTemporalSubscriptions; | |
| 789 | +} | |
| 790 | + | |
| 791 | +void DataPublisher::SetSupportsTemporalSubscriptions(bool value) | |
| 792 | +{ | |
| 793 | + m_supportsTemporalSubscriptions = value; | |
| 794 | +} | |
| 795 | + | |
| 746 | 796 | uint32_t DataPublisher::GetCipherKeyRotationPeriod() const |
| 747 | 797 | { |
| 748 | 798 | return m_cipherKeyRotationPeriod; |
| @@ -823,4 +873,14 @@ void DataPublisher::RegisterClientConnectedCallback(const SubscriberConnectionCa · 74 unmodified lines | ||
| 823 | 873 | void DataPublisher::RegisterClientDisconnectedCallback(const SubscriberConnectionCallback& clientDisconnectedCallback) |
| 824 | 874 | { |
| 825 | 875 | m_clientDisconnectedCallback = clientDisconnectedCallback; |
| 826 | −} | |
| 876 | +} | |
| 877 | + | |
| 878 | +void DataPublisher::RegisterTemporalSubscriptionRequestedCallback(const SubscriberConnectionCallback& temporalSubscriptionRequestedCallback) | |
| 879 | +{ | |
| 880 | + m_temporalSubscriptionRequestedCallback = temporalSubscriptionRequestedCallback; | |
| 881 | +} | |
| 882 | + | |
| 883 | +void DataPublisher::RegisterTemporalProcessingIntervalChangeRequestedCallback(const SubscriberConnectionCallback& temporalProcessingIntervalChangeRequestedCallback) | |
| 884 | +{ | |
| 885 | + m_temporalProcessingIntervalChangeRequestedCallback = temporalProcessingIntervalChangeRequestedCallback; | |
| 886 | +} | |