-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assume publisher qos depth of 1 if the middleware reports the qos history as unknown #239
Changes from all commits
29161f0
331835d
b07472c
6445132
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,43 +12,37 @@ namespace foxglove { | |
constexpr auto DEFAULT_TIMEOUT = std::chrono::seconds(5); | ||
|
||
std::vector<uint8_t> connectClientAndReceiveMsg(const std::string& uri, | ||
const std::string& topic_name) { | ||
const std::string& topicName) { | ||
// Set up text message handler to resolve the promise when the topic is advertised | ||
foxglove::Client<websocketpp::config::asio_client> wsClient; | ||
auto wsClient = std::make_shared<foxglove::Client<websocketpp::config::asio_client>>(); | ||
std::promise<nlohmann::json> channelPromise; | ||
auto channelFuture = channelPromise.get_future(); | ||
wsClient.setTextMessageHandler([&topic_name, &channelPromise](const std::string& payload) { | ||
const auto msg = nlohmann::json::parse(payload); | ||
const auto& op = msg.at("op").get<std::string>(); | ||
if (op == "advertise") { | ||
for (const auto& channel : msg.at("channels")) { | ||
if (topic_name == channel.at("topic")) { | ||
channelPromise.set_value(channel); | ||
} | ||
} | ||
} | ||
}); | ||
auto channelFuture = waitForChannel(wsClient, topicName); | ||
|
||
// Connect the client and wait for the channel future | ||
if (std::future_status::ready != wsClient.connect(uri).wait_for(DEFAULT_TIMEOUT)) { | ||
if (std::future_status::ready != wsClient->connect(uri).wait_for(DEFAULT_TIMEOUT)) { | ||
throw std::runtime_error("Client failed to connect"); | ||
} else if (std::future_status::ready != channelFuture.wait_for(DEFAULT_TIMEOUT)) { | ||
throw std::runtime_error("Client failed to receive channel"); | ||
} | ||
|
||
const auto channel = channelFuture.get(); | ||
const SubscriptionId subscriptionId = 1; | ||
|
||
// Set up binary message handler to resolve when a binary message has been received | ||
std::promise<std::vector<uint8_t>> msgPromise; | ||
auto msgFuture = msgPromise.get_future(); | ||
wsClient.setBinaryMessageHandler([&msgPromise](const uint8_t* data, size_t dataLength) { | ||
wsClient->setBinaryMessageHandler([&msgPromise](const uint8_t* data, size_t dataLength) { | ||
if (ReadUint32LE(data + 1) != subscriptionId) { | ||
return; | ||
} | ||
const size_t offset = 1 + 4 + 8; | ||
std::vector<uint8_t> dataCopy(dataLength - offset); | ||
std::memcpy(dataCopy.data(), data + offset, dataLength - offset); | ||
msgPromise.set_value(std::move(dataCopy)); | ||
}); | ||
|
||
// Subscribe to the channel that corresponds to the topic | ||
const auto channelId = channelFuture.get().at("id").get<foxglove::ChannelId>(); | ||
wsClient.subscribe({{1, channelId}}); | ||
wsClient->subscribe({{subscriptionId, channel.id}}); | ||
|
||
// Wait until we have received a binary message | ||
if (std::future_status::ready != msgFuture.wait_for(DEFAULT_TIMEOUT)) { | ||
|
@@ -118,6 +112,30 @@ std::future<Service> waitForService(std::shared_ptr<ClientInterface> client, | |
return future; | ||
} | ||
|
||
std::future<Channel> waitForChannel(std::shared_ptr<ClientInterface> client, | ||
const std::string& topicName) { | ||
auto promise = std::make_shared<std::promise<Channel>>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why shared_ptr? The std::promise example code seems to allocate a promise on the stack and still move it into a thread or lambda. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember that John and I had some issues with that but don't remember exactly why. Will see what I can do once I created a new release |
||
auto future = promise->get_future(); | ||
|
||
client->setTextMessageHandler( | ||
[promise = std::move(promise), topicName](const std::string& payload) mutable { | ||
const auto msg = nlohmann::json::parse(payload); | ||
const auto& op = msg["op"].get<std::string>(); | ||
|
||
if (op == "advertise") { | ||
const auto channels = msg["channels"].get<std::vector<Channel>>(); | ||
for (const auto& channel : channels) { | ||
if (channel.topic == topicName) { | ||
promise->set_value(channel); | ||
break; | ||
} | ||
} | ||
} | ||
}); | ||
|
||
return future; | ||
} | ||
|
||
// Explicit template instantiation | ||
template class Client<websocketpp::config::asio_client>; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be a shared_ptr? Would unique_ptr work? I don't see the ownership being actually shared anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, will see what I can do. Can just pass a raw pointer to
waitForChannel
then