Skip to content

Commit

Permalink
Improve zero conf announce reliability.
Browse files Browse the repository at this point in the history
* Make sure the even loop was entered before trying to announce
the TDM on zeron conf.

* Make sure the server are accepting connections by the TDM is
announced on zero conf.

* Refresh the announce every few seconds in case there
was some spurious failure.

This changes should make zero conf a bit more reliable and
avoid some of the issues where the launcher doesn't see the
TDM
  • Loading branch information
Corentin Jabot committed Sep 1, 2021
1 parent 10aee87 commit 90bca0d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 37 deletions.
39 changes: 16 additions & 23 deletions aseba/thymio-device-manager/aseba_node_registery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ aseba_node_registery::aseba_node_registery(boost::asio::execution_context& io_co
, m_discovery_socket(static_cast<boost::asio::io_context&>(io_context))
, m_nodes_service_desc("mobsya") {
m_nodes_service_desc.name(fmt::format("Thymio Device Manager on {}", boost::asio::ip::host_name()));

// update_discovery();
}

void aseba_node_registery::add_node(std::shared_ptr<aseba_node> node) {
Expand Down Expand Up @@ -114,48 +112,43 @@ void aseba_node_registery::set_ws_endpoint(const boost::asio::ip::tcp::endpoint&
m_ws_endpoint = endpoint;
}

void aseba_node_registery::set_discovery() {
update_discovery();
void aseba_node_registery::announce_on_zeroconf() {
// Make sure we have entered the event loop before announcing ourself
boost::asio::post(boost::asio::get_associated_executor(this),
boost::bind(&aseba_node_registery::do_announce_on_zeroconf, this));
}

void aseba_node_registery::update_discovery() {

if(m_updating_discovery) {
m_discovery_needs_update = true;
return;
}
void aseba_node_registery::do_announce_on_zeroconf() {
m_nodes_service_desc.properties(build_discovery_properties());

m_discovery_needs_update = false;
m_updating_discovery = true;
m_discovery_socket.async_announce(
m_nodes_service_desc,
std::bind(&aseba_node_registery::on_update_discovery_complete, this, std::placeholders::_1));
std::bind(&aseba_node_registery::on_announce_complete, this, std::placeholders::_1));
}

void aseba_node_registery::on_update_discovery_complete(const boost::system::error_code& ec) {
void aseba_node_registery::on_announce_complete(const boost::system::error_code& ec) {
if(ec) {
mLogError("Discovery : {}", ec.message());
m_discovery_needs_update = true;
} else {
mLogTrace("Discovery : update complete");
}
m_updating_discovery = false;
if(m_discovery_needs_update) {
boost::asio::post(boost::asio::get_associated_executor(this),
boost::bind(&aseba_node_registery::update_discovery, this));
}

// Refresh the zeroconf info every few seconds in case they get lost
// or corrupted.
auto timer = std::make_shared<boost::asio::deadline_timer>(get_io_context());
timer->expires_from_now(boost::posix_time::seconds(5));
auto cb = boost::asio::bind_executor(get_io_context().get_executor(), [timer, this](const boost::system::error_code& ec) {
do_announce_on_zeroconf();
});
timer->async_wait(std::move(cb));
}


aware::contact::property_map_type aseba_node_registery::build_discovery_properties() const {
aware::contact::property_map_type map;
map["uuid"] = boost::uuids::to_string(m_service_uid);
map["_ws-port"] = "8597"; //HACK adding some unused description to correct bug in avahi
if(m_ws_endpoint.port())
map["ws-port"] = std::to_string(m_ws_endpoint.port());
mLogTrace("=> WS port discovery on {}", map["ws-port"]);
map["_ws-port2"] = "8597"; //HACK adding some unused description to correct bug in avahi
return map;
}

Expand Down
9 changes: 3 additions & 6 deletions aseba/thymio-device-manager/aseba_node_registery.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class aseba_node_registery : public boost::asio::detail::service_base<aseba_node

void set_tcp_endpoint(const boost::asio::ip::tcp::endpoint& endpoint);
void set_ws_endpoint(const boost::asio::ip::tcp::endpoint& endpoint);
void set_discovery();
void announce_on_zeroconf();

node_map nodes() const;
std::shared_ptr<aseba_node> node_from_id(const node_id&) const;
Expand All @@ -48,8 +48,8 @@ class aseba_node_registery : public boost::asio::detail::service_base<aseba_node
void save_group_affiliation(const aseba_node& node);
void restore_group_affiliation(const aseba_node& node);

void update_discovery();
void on_update_discovery_complete(const boost::system::error_code&);
void do_announce_on_zeroconf();
void on_announce_complete(const boost::system::error_code&);
aware::contact::property_map_type build_discovery_properties() const;

node_map::const_iterator find(const std::shared_ptr<aseba_node>& node) const;
Expand All @@ -73,9 +73,6 @@ class aseba_node_registery : public boost::asio::detail::service_base<aseba_node
// Endpoint of the WebSocket - So we can expose the port on zeroconf
boost::asio::ip::tcp::endpoint m_ws_endpoint;

bool m_updating_discovery = false;
bool m_discovery_needs_update = false;

boost::signals2::signal<void(std::shared_ptr<aseba_node>, node_id, aseba_node::status)>
m_node_status_changed_signal;
friend class node_status_monitor;
Expand Down
19 changes: 11 additions & 8 deletions aseba/thymio-device-manager/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,18 @@ void run_service(boost::asio::io_context& ctx) {

[[maybe_unused]] mobsya::wireless_configurator_service& ws =
boost::asio::make_service<mobsya::wireless_configurator_service>(ctx);
// ws.enable();
ws.enable();

// Create a server for regular tcp connection
mobsya::application_server<mobsya::tcp::socket> tcp_server(ctx, 0);
node_registery.set_tcp_endpoint(tcp_server.endpoint());
tcp_server.accept();

mobsya::aseba_tcp_acceptor aseba_tcp_acceptor(ctx);

// Create a server for websocket
mobsya::application_server<mobsya::websocket_t> websocket_server(ctx, 8597);
node_registery.set_ws_endpoint(websocket_server.endpoint());
websocket_server.accept();

// Enable Bonjour, Zeroconf
node_registery.set_discovery();

mLogTrace("=> TCP Server connected on {}", tcp_server.endpoint().port());
mLogTrace("=> WS Server connected on {}", websocket_server.endpoint().port());

#ifdef MOBSYA_TDM_ENABLE_USB
mobsya::usb_server usb_server(ctx, {mobsya::THYMIO2_DEVICE_ID, mobsya::THYMIO_WIRELESS_DEVICE_ID});
Expand All @@ -79,6 +72,16 @@ void run_service(boost::asio::io_context& ctx) {
serial_server.accept();
#endif
aseba_tcp_acceptor.accept();
websocket_server.accept();
tcp_server.accept();

mLogTrace("=> TCP Server started on {}", tcp_server.endpoint().port());
mLogTrace("=> WS Server started on {}", websocket_server.endpoint().port());

// Enable Bonjour/Zeroconf
// Make sure this is done after the different servers are started and accept connections
// So that clients can connect to discovered services
node_registery.announce_on_zeroconf();

ctx.run();
}
Expand Down

0 comments on commit 90bca0d

Please sign in to comment.