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 | using namespace GSF::TimeSeries; | 36 | using namespace GSF::TimeSeries; |
| 37 | using namespace GSF::TimeSeries::Transport; | 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 | DataPublisher::DataPublisher(const TcpEndPoint& endpoint) : | 39 | DataPublisher::DataPublisher(const TcpEndPoint& endpoint) : |
| 52 | m_nodeID(NewGuid()), | 40 | m_nodeID(NewGuid()), |
| 53 | m_securityMode(SecurityMode::None), | 41 | m_securityMode(SecurityMode::None), |
| 54 | m_allowMetadataRefresh(true), | 42 | m_allowMetadataRefresh(true), |
| 55 | m_allowNaNValueFilter(true), | 43 | m_allowNaNValueFilter(true), |
| 56 | m_forceNaNValueFilter(false), | 44 | m_forceNaNValueFilter(false), |
| 45 | m_supportsTemporalSubscriptions(false), | ||
| 57 | m_cipherKeyRotationPeriod(60000), | 46 | m_cipherKeyRotationPeriod(60000), |
| 58 | m_userData(nullptr), | 47 | m_userData(nullptr), |
| 59 | m_disposing(false), | 48 | m_disposing(false), |
| @@ -116,19 +105,21 @@ void DataPublisher::AcceptConnection(const SubscriberConnectionPtr& connection, · 56 unmodified lines | |||
| 116 | m_subscriberConnectionsLock.unlock(); | 105 | m_subscriberConnectionsLock.unlock(); |
| 117 | 106 | ||
| 118 | connection->Start(); | 107 | connection->Start(); |
| 119 | DispatchClientConnected(connection->GetSubscriberID(), connection->GetConnectionID()); | 108 | DispatchClientConnected(connection); |
| 120 | } | 109 | } |
| 121 | 110 | ||
| 122 | StartAccept(); | 111 | StartAccept(); |
| 123 | } | 112 | } |
| 124 | 113 | ||
| 114 | void DataPublisher::ConnectionTerminated(const SubscriberConnectionPtr& connection) | ||
| 115 | { | ||
| 116 | DispatchClientDisconnected(connection); | ||
| 117 | } | ||
| 118 | |||
| 125 | void DataPublisher::RemoveConnection(const SubscriberConnectionPtr& connection) | 119 | void DataPublisher::RemoveConnection(const SubscriberConnectionPtr& connection) |
| 126 | { | 120 | { |
| 127 | m_subscriberConnectionsLock.lock(); | 121 | m_subscriberConnectionsLock.lock(); |
| 128 | 122 | m_subscriberConnections.erase(connection); | |
| 129 | if (m_subscriberConnections.erase(connection)) | ||
| 130 | DispatchClientDisconnected(connection->GetSubscriberID(), connection->GetConnectionID()); | ||
| 131 | |||
| 132 | m_subscriberConnectionsLock.unlock(); | 123 | m_subscriberConnectionsLock.unlock(); |
| 133 | } | 124 | } |
| 134 | 125 | ||
| @@ -169,16 +160,28 @@ void DataPublisher::DispatchErrorMessage(const string& message) · 34 unmodified lines | |||
| 169 | Dispatch(&ErrorMessageDispatcher, reinterpret_cast<const uint8_t*>(message.c_str()), 0, messageSize); | 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); | 177 | SubscriberConnection* connectionReference = &*connection; |
| 175 | Dispatch(&ClientConnectedDispatcher, reinterpret_cast<uint8_t*>(&data), 0, sizeof(SubscriberConnectionInfo**)); | 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); | 183 | SubscriberConnection* connectionReference = &*connection; |
| 181 | Dispatch(&ClientDisconnectedDispatcher, reinterpret_cast<uint8_t*>(&data), 0, sizeof(SubscriberConnectionInfo**)); | 184 | Dispatch(&TemporalProcessingIntervalChangeRequestedDispatcher, reinterpret_cast<uint8_t*>(&connectionReference), 0, sizeof(SubscriberConnection**)); |
| 182 | } | 185 | } |
| 183 | 186 | ||
| 184 | // Dispatcher function for status messages. Decodes the message and provides it to the user via the status message callback. | 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 | void DataPublisher::ClientConnectedDispatcher(DataPublisher* source, const vector<uint8_t>& buffer) | 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 | if (source != nullptr) | 215 | if (source != nullptr) |
| 213 | { | 216 | { |
| 214 | const SubscriberConnectionCallback clientConnectedCallback = source->m_clientConnectedCallback; | 217 | const SubscriberConnectionCallback clientConnectedCallback = source->m_clientConnectedCallback; |
| 215 | 218 | ||
| 216 | if (clientConnectedCallback != nullptr) | 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 | void DataPublisher::ClientDisconnectedDispatcher(DataPublisher* source, const std::vector<uint8_t>& buffer) | 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 | if (source != nullptr) | 228 | if (source != nullptr) |
| 228 | { | 229 | { |
| 229 | const SubscriberConnectionCallback clientDisconnectedCallback = source->m_clientDisconnectedCallback; | 230 | const SubscriberConnectionCallback clientDisconnectedCallback = source->m_clientDisconnectedCallback; |
| 230 | 231 | ||
| 231 | if (clientDisconnectedCallback != nullptr) | 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 | int32_t DataPublisher::GetColumnIndex(const GSF::Data::DataTablePtr& table, const std::string& columnName) | 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 | void DataPublisher::PublishMeasurements(const vector<Measurement>& measurements) | 711 | void DataPublisher::PublishMeasurements(const vector<Measurement>& measurements) |
| 685 | { | 712 | { |
| 686 | for (const auto& connection : m_subscriberConnections) | 713 | vector<MeasurementPtr> measurementPtrs; |
| 687 | connection->PublishMeasurements(measurements); | 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 | void DataPublisher::PublishMeasurements(const vector<MeasurementPtr>& measurements) | 723 | void DataPublisher::PublishMeasurements(const vector<MeasurementPtr>& measurements) |
| 691 | { | 724 | { |
| 725 | m_subscriberConnectionsLock.lock(); | ||
| 726 | |||
| 692 | for (const auto& connection : m_subscriberConnections) | 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 | const GSF::Guid& DataPublisher::GetNodeID() const | 736 | const GSF::Guid& DataPublisher::GetNodeID() const |
| @@ -743,6 +783,16 @@ void DataPublisher::SetNaNValueFilterForced(bool forced) · 46 unmodified lines | |||
| 743 | m_forceNaNValueFilter = forced; | 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 | uint32_t DataPublisher::GetCipherKeyRotationPeriod() const | 796 | uint32_t DataPublisher::GetCipherKeyRotationPeriod() const |
| 747 | { | 797 | { |
| 748 | return m_cipherKeyRotationPeriod; | 798 | return m_cipherKeyRotationPeriod; |
| @@ -823,4 +873,14 @@ void DataPublisher::RegisterClientConnectedCallback(const SubscriberConnectionCa · 74 unmodified lines | |||
| 823 | void DataPublisher::RegisterClientDisconnectedCallback(const SubscriberConnectionCallback& clientDisconnectedCallback) | 873 | void DataPublisher::RegisterClientDisconnectedCallback(const SubscriberConnectionCallback& clientDisconnectedCallback) |
| 824 | { | 874 | { |
| 825 | m_clientDisconnectedCallback = clientDisconnectedCallback; | 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 | } | ||