{
public:
Impl(const std::string& address, Callback callback, void* data);
+ Impl(const Impl& rhs);
~Impl();
bool stop();
+ bool connected() const { return m_connected; }
bool request(TYPE type, const std::string& userName, const std::string& password, const PAIRS& pairs);
ProtoParser m_parser;
+ bool m_connected;
+
void m_writeHeader(TYPE type, const std::string& userName, const std::string& password);
void m_writePairBlock(const PAIRS& source);
PAIRS m_readPairBlock();
{
}
+STG_CLIENT::STG_CLIENT(const STG_CLIENT& rhs)
+ : m_impl(new Impl(*rhs.m_impl))
+{
+}
+
STG_CLIENT::~STG_CLIENT()
{
}
return m_impl->stop();
}
+bool STG_CLIENT::connected() const
+{
+ return m_impl->connected();
+}
+
bool STG_CLIENT::request(TYPE type, const std::string& userName, const std::string& password, const PAIRS& pairs)
{
return m_impl->request(type, userName, password, pairs);
return false;
}
+bool STG_CLIENT::reconnect()
+{
+ if (stgClient == NULL)
+ {
+ RadLog("Connection is not configured.");
+ return false;
+ }
+ if (!stgClient->stop())
+ {
+ RadLog("Failed to drop previous connection.");
+ return false;
+ }
+ try {
+ STG_CLIENT* old = stgClient;
+ stgClient = new STG_CLIENT(*old);
+ delete old;
+ return true;
+ } catch (const ChannelConfig::Error& ex) {
+ // TODO: Log it
+ RadLog("Client configuration error: %s.", ex.what());
+ }
+ return false;
+}
+
STG_CLIENT::Impl::Impl(const std::string& address, Callback callback, void* data)
: m_config(address),
m_sock(connect()),
m_lastActivity(m_lastPing),
m_callback(callback),
m_data(data),
- m_parser(&STG_CLIENT::Impl::process, this)
+ m_parser(&STG_CLIENT::Impl::process, this),
+ m_connected(true)
+{
+ int res = pthread_create(&m_thread, NULL, &STG_CLIENT::Impl::run, this);
+ if (res != 0)
+ throw Error("Failed to create thread: " + std::string(strerror(errno)));
+}
+
+STG_CLIENT::Impl::Impl(const Impl& rhs)
+ : m_config(rhs.m_config),
+ m_sock(connect()),
+ m_running(false),
+ m_stopped(true),
+ m_lastPing(time(NULL)),
+ m_lastActivity(m_lastPing),
+ m_callback(rhs.m_callback),
+ m_data(rhs.m_data),
+ m_parser(&STG_CLIENT::Impl::process, this),
+ m_connected(true)
{
int res = pthread_create(&m_thread, NULL, &STG_CLIENT::Impl::run, this);
if (res != 0)
bool STG_CLIENT::Impl::stop()
{
+ m_connected = false;
+
if (m_stopped)
return true;
m_running = tick();
}
+ m_connected = false;
m_stopped = true;
}
ssize_t res = ::send(impl.m_sock, buf, size, MSG_NOSIGNAL);
if (res < 0)
{
+ impl.m_connected = false;
RadLog("Failed to write data: %s.", strerror(errno));
//conn.m_logger("Failed to write pong to '" + conn.m_remote + "': " + strerror(errno));
return false;
typedef bool (*Callback)(void* /*data*/, const RESULT& /*result*/, bool /*status*/);
STG_CLIENT(const std::string& address, Callback callback, void* data);
+ STG_CLIENT(const STG_CLIENT& rhs);
~STG_CLIENT();
bool stop();
+ bool connected() const;
static STG_CLIENT* get();
static bool configure(const std::string& address, Callback callback, void* data);
+ static bool reconnect();
bool request(TYPE type, const std::string& userName, const std::string& password, const PAIRS& pairs);