29 #include <boost/lexical_cast.hpp> 31 #include <boost/asio/ip/address.hpp> 33 #include <boost/format.hpp> 35 #include <rsc/runtime/ContainerIO.h> 42 using namespace boost;
45 using boost::asio::ip::tcp;
56 logger(Logger::getLogger(
"rsb.transport.socket.Factory")), asioService(
58 RSCDEBUG(
logger,
"Constructed and asio service created");
62 RSCDEBUG(
logger,
"Destructing");
65 template<
class BusType>
67 bool tcpnodelay, map<
Endpoint, boost::weak_ptr<BusType> >& map) {
68 typename std::map<Endpoint, boost::weak_ptr<BusType> >::const_iterator it;
69 if ((it = map.find(endpoint)) != map.end()) {
70 boost::shared_ptr<BusType> result = it->second.lock();
74 "Found existing bus " << result
75 <<
" without resolving");
81 return boost::shared_ptr<BusType>();
87 RSCDEBUG(
logger,
"Was asked for a bus client for " << host <<
":" << port);
99 RSCDEBUG(
logger,
"Did not find bus client without resolving");
107 RSCDEBUG(
logger,
"Resolving endpoint")
108 tcp::resolver resolver(*this->
asioService->getService());
109 tcp::resolver::query query(host, lexical_cast<string>(port),
110 tcp::resolver::query::numeric_service);
111 for (tcp::resolver::iterator endpointIterator = resolver.resolve(query);
112 endpointIterator != tcp::resolver::iterator();
113 ++endpointIterator) {
114 endpoint =
Endpoint(endpointIterator->host_name(), port);
124 for (tcp::resolver::iterator endpointIterator = resolver.resolve(query);
125 endpointIterator != tcp::resolver::iterator();
126 ++endpointIterator) {
127 endpoint =
Endpoint(endpointIterator->host_name(), port);
128 RSCDEBUG(
logger,
"Trying endpoint " << endpointIterator->endpoint());
129 socket.reset(
new tcp::socket(*this->
asioService->getService()));
130 boost::system::error_code error;
131 socket->connect(endpointIterator->endpoint(), error);
133 RSCDEBUG(
logger,
"Success");
136 RSCDEBUG(
logger,
"Failed: " << error.message());
140 throw runtime_error(str(format(
"Could not connect to any of the endpoints to which %1%:%2% resolved.")
146 RSCDEBUG(
logger,
"Did not find bus client after resolving; creating a new one");
152 result->addConnection(connection);
153 connection->startReceiving();
155 RSCDEBUG(
logger,
"Created new bus client " << result);
163 RSCDEBUG(
logger,
"Was asked for a bus server for " << host <<
":" << port);
175 RSCDEBUG(
logger,
"Did not find bus server; creating a new one");
185 RSCDEBUG(
logger,
"Created new bus server " << result);
191 const std::string& host,
192 const boost::uint16_t& port,
195 boost::mutex::scoped_lock lock(this->
busMutex);
197 switch (serverMode) {
205 }
catch (
const std::exception& e) {
207 "Could not create server for bus: " << e.what() <<
"; trying to access bus as client");
212 throw invalid_argument(
"Impossible Server enum value received");
218 if (bus->isTcpnodelay() != tcpnodelay) {
219 throw invalid_argument(str(format(
"Requested tcpnodelay option %1% does not match existing option %2%")
220 % tcpnodelay % bus->isTcpnodelay()));
225 static boost::mutex mutex;
227 boost::mutex::scoped_lock lock(mutex);
228 if (!defaultFactory) {
229 defaultFactory.reset(
new Factory);
231 return defaultFactory;
rsc::logging::LoggerPtr logger
Instances of this class provide access to a socket-based bus.
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
boost::shared_ptr< BusConnection > BusConnectionPtr
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
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)