29 #include <boost/lexical_cast.hpp> 31 #include <boost/asio/ip/address.hpp> 33 #include <boost/format.hpp> 35 #include <rsc/runtime/ContainerIO.h> 43 using namespace boost;
46 using boost::asio::ip::tcp;
57 logger(Logger::getLogger(
"rsb.transport.socket.Factory")), asioService(
59 RSCDEBUG(
logger,
"Constructed and asio service created");
63 RSCDEBUG(
logger,
"Destructing");
66 template<
class BusType>
68 bool tcpnodelay, map<
Endpoint, boost::weak_ptr<BusType> >& map) {
69 typename std::map<Endpoint, boost::weak_ptr<BusType> >::const_iterator it;
70 if ((it = map.find(endpoint)) != map.end()) {
71 boost::shared_ptr<BusType> result = it->second.lock();
75 "Found existing bus " << result
76 <<
" without resolving");
82 return boost::shared_ptr<BusType>();
88 RSCDEBUG(
logger,
"Was asked for a bus client for " << host <<
":" << port);
100 RSCDEBUG(
logger,
"Did not find bus client without resolving");
108 RSCDEBUG(
logger,
"Resolving endpoint")
109 tcp::resolver resolver(*this->
asioService->getService());
110 tcp::resolver::query query(host, lexical_cast<string>(port),
111 tcp::resolver::query::numeric_service);
112 for (tcp::resolver::iterator endpointIterator = resolver.resolve(query);
113 endpointIterator != tcp::resolver::iterator();
114 ++endpointIterator) {
115 endpoint =
Endpoint(endpointIterator->host_name(), port);
125 for (tcp::resolver::iterator endpointIterator = resolver.resolve(query);
126 endpointIterator != tcp::resolver::iterator();
127 ++endpointIterator) {
128 endpoint =
Endpoint(endpointIterator->host_name(), port);
129 RSCDEBUG(
logger,
"Trying endpoint " << endpointIterator->endpoint());
130 socket.reset(
new tcp::socket(*this->
asioService->getService()));
131 boost::system::error_code error;
132 socket->connect(endpointIterator->endpoint(), error);
134 RSCDEBUG(
logger,
"Success");
137 RSCDEBUG(
logger,
"Failed: " << error.message());
141 throw runtime_error(str(format(
"Could not connect to any of the endpoints to which %1%:%2% resolved.")
147 RSCDEBUG(
logger,
"Did not find bus client after resolving; creating a new one");
153 result->addConnection(connection);
154 connection->startReceiving();
156 RSCDEBUG(
logger,
"Created new bus client " << result);
164 RSCDEBUG(
logger,
"Was asked for a bus server for " << host <<
":" << port);
176 RSCDEBUG(
logger,
"Did not find bus server; creating a new one");
186 RSCDEBUG(
logger,
"Created new bus server " << result);
192 const std::string& host,
193 const boost::uint16_t& port,
196 boost::mutex::scoped_lock lock(this->
busMutex);
198 switch (serverMode) {
206 }
catch (
const std::exception& e) {
208 "Could not create server for bus: " << e.what() <<
"; trying to access bus as client");
213 throw invalid_argument(
"Impossible Server enum value received");
219 if (bus->isTcpnodelay() != tcpnodelay) {
220 throw invalid_argument(str(format(
"Requested tcpnodelay option %1% does not match existing option %2%")
221 % tcpnodelay % bus->isTcpnodelay()));
226 static boost::mutex mutex;
228 boost::mutex::scoped_lock lock(mutex);
229 if (!defaultFactory) {
230 defaultFactory.reset(
new Factory);
232 return defaultFactory;
rsc::logging::LoggerPtr logger
boost::shared_ptr< BusType > searchInMap(const Endpoint &endpoint, bool tcpnodelay, std::map< Endpoint, boost::weak_ptr< BusType > > &map)
Searches inside a given map for an active pointer to a Bus instance matching the given query...
boost::shared_ptr< Factory > FactoryPtr
A class that keeps a boost asio service alive as long as this class lives.
boost::shared_ptr< boost::asio::ip::tcp::socket > SocketPtr
boost::shared_ptr< BusServer > BusServerPtr
FactoryPtr getDefaultFactory()
The singleton instance of this class is responsible for managing bus provider objects.
static void checkOptions(BusPtr bus, bool tcpnodelay)
AsioServiceContextPtr asioService
boost::shared_ptr< BusConnection > BusConnectionPtr
std::pair< std::string, boost::uint16_t > Endpoint
A facade around BusServer instances to allow breaking dependency cycles.
Instances of this class implement connections to a socket-based bus.
Instances of this class provide access to a socket-based bus for local and remote bus clients...
BusPtr getBus(const Server &serverMode, const std::string &host, const boost::uint16_t &port, bool tcpnodelay)
Returns either a BusClient or Server depending on the chosen serverMode and the existence of a server...
BusServerPtr getBusServerFor(const std::string &host, boost::uint16_t port, bool tcpnodelay)
boost::shared_ptr< Bus > BusPtr
BusPtr getBusClientFor(const std::string &host, boost::uint16_t port, bool tcpnodelay)