View on GitHub

Asio Service Discovery

Components for service discovery via udp multicasting. It's using boost::asio for async networking. It's non-blocking and non-locking.

Download this project as a .zip file Download this project as a tar.gz file
service_announcer.hpp
1 //
2 // service_announcer.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2015 Benjamin Schulz (beschulz at betabugs dot de)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef BB_SERVICE_ANNOUNCER_HPP_INCLUDED
12 #define BB_SERVICE_ANNOUNCER_HPP_INCLUDED
13 
14 #pragma once
15 
16 #include <iostream>
17 #include <sstream>
18 #include <boost/asio.hpp>
19 
20 namespace betabugs {
21 namespace networking {
22 
39 {
40  public:
47  boost::asio::io_service& io_service,
48  const std::string& service_name,
49  const unsigned short service_port,
50  const unsigned short multicast_port = 30001,
51  const boost::asio::ip::address& multicast_address = boost::asio::ip::address::from_string("239.255.0.1")
52  )
53  : endpoint_(multicast_address, multicast_port)
54  , socket_(io_service, endpoint_.protocol())
55  , timer_(io_service)
56  , service_name_(service_name)
57  , service_port_(service_port)
58  {
59  write_message();
60  }
61 
62  private:
63  void handle_send_to(const boost::system::error_code& error)
64  {
65  if (error)
66  {
67  std::cerr << error.message() << std::endl;
68  }
69  else
70  {
71  timer_.expires_from_now(boost::posix_time::seconds(1));
72  timer_.async_wait(
73  [this](const boost::system::error_code& error)
74  {
75  this->handle_timeout(error);
76  });
77  }
78  }
79 
80  void handle_timeout(const boost::system::error_code& error)
81  {
82  if (!error)
83  {
84  write_message();
85  }
86  else
87  {
88  std::cerr << error.message() << std::endl;
89  }
90  }
91 
92  void write_message()
93  {
94  std::ostringstream os;
95  boost::system::error_code error_code;
96 
97  // "my_service_name:my_computer:2052"
98  os << service_name_
99  << ":" << boost::asio::ip::host_name(error_code)
100  << ":" << service_port_;
101 
102  if (error_code)
103  {
104  std::cerr << error_code.message() << std::endl;
105  }
106 
107  message_ = os.str();
108 
109  socket_.async_send_to(
110  boost::asio::buffer(message_), endpoint_,
111  [this](const boost::system::error_code& error, std::size_t /*bytes_transferred*/)
112  {
113  this->handle_send_to(error);
114  }
115  );
116  }
117 
118  private:
119  boost::asio::ip::udp::endpoint endpoint_;
120  boost::asio::ip::udp::socket socket_;
121  boost::asio::deadline_timer timer_;
122  std::string message_;
123  const std::string service_name_;
124  const unsigned short service_port_;
125 };
126 
127 }
128 }
129 
130 #endif /* BB_SERVICE_ANNOUNCER_HPP_INCLUDED */
service_announcer(boost::asio::io_service &io_service, const std::string &service_name, const unsigned short service_port, const unsigned short multicast_port=30001, const boost::asio::ip::address &multicast_address=boost::asio::ip::address::from_string("239.255.0.1"))
Definition: service_announcer.hpp:46
Definition: service_announcer.hpp:38