-
Notifications
You must be signed in to change notification settings - Fork 173
Peer discovery
The Peer Discovery APIs allows to make use of IPv4/IPv6 multicast to publish information about services available on a local network and advertise a local service.
Without peer discovery, DHT nodes need to be bootstrapped to any running node to join a DHT network.
See Joining an existing network.
Use the peer_discover
and peer_publish
configuration options to enable DHT node discovery and/or advertisement.
When enabled, DHT peers will automatically add each others to their routing tables upon discovery, creating an ad-hoc DHT network on top of the local network.
Peer Discovery features are exposed by the dht::PeerDiscovery
class, which can be used independently from DHT nodes and allows to publish and subscribe to any number of different services.
static const std::string MY_SERVICE_NAME = "my_service";
static constexpr in_port_t MULTICAST_PORT = 2222;
// A single instance & port can be used for both advertising and discovering of multiple different services
dht::PeerDiscovery discovery(MULTICAST_PORT);
dht::PeerDiscovery
can be considered thread-safe: its methods can be safely called from different threads.
Peer discovery makes use of msgpack to serialize service data and provides easy to use APIs to manage service data serialization with msgpack-c.
// Using msgpack serialization
struct ExampleServiceData {
in_port_t service_port;
uint32_t some_id;
std::string some_param;
MSGPACK_DEFINE(service_port, some_id, some_param)
};
// using custom serialization
using ExampleServiceData = std::vector<char>; // or std::vector<uint8_t>
ExampleServiceData my_data {...};
discovery.startPublish(MY_SERVICE_NAME, my_data);
// later
discovery.stopPublish(MY_SERVICE_NAME);
discovery.startDiscovery<ExampleServiceData>(MY_SERVICE_NAME,
[](ExampleServiceData&& d, dht::SockAddr&& addr) {
addr.setPort(d.service_port);
std::cout << "Discovered some peer for our service at " << addr.toString() << std::cout;
});
// later
discovery.stopDiscovery(MY_SERVICE_NAME);
To completely stop advertising or publishing services, simply call stop()
, or just destroy the instance.
Calling stop()
before instance destruction allows to asynchronously release internal resources (threads & sockets).