mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[ntcore] Server: Properly handle multiple subscribers (#4717)
Previously, only the first subscriber was actually matched to a topic when a topic was created; this was a problem when later publishing values as a client could have both a topic-only subscriber and a normal subscriber, and only the first one would end up being subscribed to the topic.
This commit is contained in:
@@ -110,8 +110,9 @@ class ClientData {
|
||||
void UpdateMetaClientPub();
|
||||
void UpdateMetaClientSub();
|
||||
|
||||
// returns nullptr if there is no subscriber for that topic name
|
||||
SubscriberData* GetSubscriber(std::string_view name, bool special);
|
||||
std::span<SubscriberData*> GetSubscribers(
|
||||
std::string_view name, bool special,
|
||||
wpi::SmallVectorImpl<SubscriberData*>& buf);
|
||||
|
||||
std::string_view GetOriginalName() const { return m_originalName; }
|
||||
std::string_view GetName() const { return m_name; }
|
||||
@@ -531,14 +532,17 @@ void ClientData::UpdateMetaClientSub() {
|
||||
}
|
||||
}
|
||||
|
||||
SubscriberData* ClientData::GetSubscriber(std::string_view name, bool special) {
|
||||
std::span<SubscriberData*> ClientData::GetSubscribers(
|
||||
std::string_view name, bool special,
|
||||
wpi::SmallVectorImpl<SubscriberData*>& buf) {
|
||||
buf.resize(0);
|
||||
for (auto&& subPair : m_subscribers) {
|
||||
SubscriberData* subscriber = subPair.getSecond().get();
|
||||
if (subscriber->Matches(name, special)) {
|
||||
return subscriber;
|
||||
buf.emplace_back(subscriber);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return {buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
void ClientData4Base::ClientPublish(int64_t pubuid, std::string_view name,
|
||||
@@ -2018,14 +2022,15 @@ TopicData* SImpl::CreateTopic(ClientData* client, std::string_view name,
|
||||
}
|
||||
|
||||
// look for subscriber matching prefixes
|
||||
bool hasSubscriber = false;
|
||||
if (auto subscriber = aClient->GetSubscriber(name, topic->special)) {
|
||||
wpi::SmallVector<SubscriberData*, 16> subscribersBuf;
|
||||
auto subscribers =
|
||||
aClient->GetSubscribers(name, topic->special, subscribersBuf);
|
||||
for (auto subscriber : subscribers) {
|
||||
topic->subscribers.Add(subscriber);
|
||||
hasSubscriber = true;
|
||||
}
|
||||
|
||||
// don't announce to this client if no subscribers
|
||||
if (!hasSubscriber) {
|
||||
if (subscribers.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user