X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/fd41f8dfd1133e89f6b5ac675fe2b5068b6bb652..d78d51f3932ed3d3466e53eb7c7786d5d8216cc0:/projects/rlm_stg/stg_client.cpp diff --git a/projects/rlm_stg/stg_client.cpp b/projects/rlm_stg/stg_client.cpp index 0e6bdc7b..8c7ed9b9 100644 --- a/projects/rlm_stg/stg_client.cpp +++ b/projects/rlm_stg/stg_client.cpp @@ -209,9 +209,11 @@ class STG_CLIENT::Impl { 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); @@ -234,6 +236,8 @@ private: 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(); @@ -298,6 +302,11 @@ STG_CLIENT::STG_CLIENT(const std::string& address, Callback callback, void* data { } +STG_CLIENT::STG_CLIENT(const STG_CLIENT& rhs) + : m_impl(new Impl(*rhs.m_impl)) +{ +} + STG_CLIENT::~STG_CLIENT() { } @@ -307,6 +316,11 @@ bool STG_CLIENT::stop() 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); @@ -324,6 +338,30 @@ bool STG_CLIENT::configure(const std::string& address, Callback callback, void* try { stgClient = new STG_CLIENT(address, callback, data); return true; + } catch (const std::exception& ex) { + // TODO: Log it + RadLog("Client configuration error: %s.", ex.what()); + } + 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()); @@ -340,7 +378,25 @@ STG_CLIENT::Impl::Impl(const std::string& address, Callback callback, void* data 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) @@ -356,6 +412,8 @@ STG_CLIENT::Impl::~Impl() bool STG_CLIENT::Impl::stop() { + m_connected = false; + if (m_stopped) return true; @@ -411,8 +469,6 @@ void STG_CLIENT::Impl::runImpl() if (errno == EINTR) continue; RadLog("'select' is failed: %s", strerror(errno)); - //m_error = std::string("'select' is failed: '") + strerror(errno) + "'."; - //m_logger(m_error); break; } @@ -428,6 +484,7 @@ void STG_CLIENT::Impl::runImpl() m_running = tick(); } + m_connected = false; m_stopped = true; } @@ -472,7 +529,6 @@ int STG_CLIENT::Impl::connectTCP() shutdown(fd, SHUT_RDWR); close(fd); RadLog("'connect' is failed: %s", strerror(errno)); - // TODO: log it. continue; } freeaddrinfo(ais); @@ -509,8 +565,7 @@ bool STG_CLIENT::Impl::read() ssize_t res = ::read(m_sock, buffer.data(), buffer.size()); if (res < 0) { - RadLog("Failed to read data: ", strerror(errno)); - //m_logger("Failed to read data from '" + m_remote + "': " + strerror(errno)); + RadLog("Failed to read data: %s", strerror(errno)); return false; } m_lastActivity = time(NULL); @@ -612,8 +667,8 @@ bool STG_CLIENT::Impl::write(void* data, const char* buf, size_t size) 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; } size -= res;