//*****************************************************************************
// RCF - Remote Call Framework
// Copyright (c) 2005. All rights reserved.
// Developed by Jarl Lindrud.
// Contact: jlindrud@hotmail.com .
//*****************************************************************************
#ifndef INCLUDE_RCF_PUBLISHINGSERVICE_HPP
#define INCLUDE_RCF_PUBLISHINGSERVICE_HPP
#include <map>
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <RCF/GetInterfaceName.hpp>
#include <RCF/Service.hpp>
#include <RCF/ThreadLibrary.hpp>
namespace RCF {
class RcfServer;
class I_RcfClient;
class Session;
class I_ClientTransport;
typedef boost::shared_ptr<I_RcfClient> RcfClientPtr;
struct Publisher
{
std::string name;
RcfClientPtr multicastClient;
};
struct PublishingOptions
{
unsigned int pingInterval;
};
/// Service for implementing the publish part of publish/subscribe functionality.
class PublishingService :
public I_Service,
boost::noncopyable
{
public:
PublishingService();
/// Creates and stores a publisher object, i.e. a RcfClient<Interface> object with an underlying multicasting transport.
/// \param Interface RCF interface to publish.
/// \param publisherName Name through which this publisher will be accessed.
/// \return True if ok, false otherwise.
template<typename Interface>
bool beginPublish(const std::string &publisherName = "");
/// Obtains a reference to the requested publisher object.
/// \param Interface RCF interface of the publisher object.
/// \param publisherName Name of the publisher object.
/// \return Reference to the publisher object.
template<typename Interface>
typename Interface::RcfClient &publish(const std::string &publisherName = "");
/// Shuts down the given publisher object.
/// \param Interface RCF interface of the publisher object.
/// \param publisherName Name of the publisher object.
/// \return True if ok, false otherwise.
template<typename Interface>
bool endPublish(const std::string &publisherName = "");
// remotely accessible
bool requestSubscription(const std::string &subscriptionName);
private:
void onServiceAdded(RcfServer &server);
void onServiceRemoved(RcfServer &server);
bool beginPublishNamed(const std::string &publisherName, RcfClientPtr rcfClientPtr);
I_RcfClient &publishNamed(const std::string &publisherName);
bool endPublishNamed(const std::string &publisherName);
void addSubscriberTransport(Session &session, const std::string &publisherName, boost::shared_ptr<I_ClientTransport> clientTransport);
ReadWriteMutex mPublishersMutex;
std::map<std::string, boost::shared_ptr<Publisher> > mPublishers;
};
typedef boost::shared_ptr<PublishingService> PublishingServicePtr;
template<typename Interface>
inline bool PublishingService::beginPublish(const std::string &publisherName_)
{
const std::string &publisherName = (publisherName_ == "") ? getInterfaceName<Interface>() : publisherName_;
typedef typename Interface::RcfClient RcfClient;
return beginPublishNamed(publisherName, RcfClientPtr(new RcfClient(ClientStub(publisherName))));
}
template<typename Interface>
inline typename Interface::RcfClient &PublishingService::publish(const std::string &publisherName_)
{
const std::string &publisherName = (publisherName_ == "") ? getInterfaceName<Interface>() : publisherName_;
return dynamic_cast<typename Interface::RcfClient &>( publishNamed(publisherName) );
}
template<typename Interface>
inline bool PublishingService::endPublish(const std::string &publisherName_)
{
const std::string &publisherName = (publisherName_ == "") ? getInterfaceName<Interface>() : publisherName_;
return endPublishNamed(publisherName);
}
} // namespace RCF
#endif // ! INCLUDE_RCF_PUBLISHINGSERVICE_HPP