Add ability to reconnect from server side (#7226)
* Add ability to reconnect from server side * Fix code smell Co-authored-by: Serhii Hadzhilov <serhii@symless.com>
This commit is contained in:
@ -51,7 +51,8 @@ void
|
||||
InverseServerSocket::bind(const NetworkAddress& addr)
|
||||
{
|
||||
Lock lock(&m_mutex);
|
||||
m_socket.connectSocket(addr);
|
||||
m_address = addr;
|
||||
m_socket.connectSocket(m_address);
|
||||
setListeningJob(true);
|
||||
}
|
||||
|
||||
@ -110,8 +111,8 @@ InverseServerSocket::serviceListening(ISocketMultiplexerJob* job,
|
||||
bool, bool write, bool error)
|
||||
{
|
||||
if (error) {
|
||||
close();
|
||||
return nullptr;
|
||||
m_socket.connectSocket(m_address);
|
||||
return job;
|
||||
}
|
||||
if (write) {
|
||||
m_events->addEvent(Event(m_events->forIListenSocket().connecting(), this));
|
||||
|
||||
@ -58,4 +58,7 @@ protected:
|
||||
Mutex m_mutex;
|
||||
IEventQueue* m_events;
|
||||
SocketMultiplexer* m_socketMultiplexer;
|
||||
|
||||
private:
|
||||
NetworkAddress m_address;
|
||||
};
|
||||
|
||||
@ -403,17 +403,20 @@ SecureSocket::freeSSL()
|
||||
// could cause events to get called on a dead object. TCPSocket
|
||||
// will do this, too, but the double-call is harmless
|
||||
setJob(NULL);
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
SSL_shutdown(m_ssl->m_ssl);
|
||||
if (m_ssl) {
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
SSL_shutdown(m_ssl->m_ssl);
|
||||
|
||||
SSL_free(m_ssl->m_ssl);
|
||||
m_ssl->m_ssl = NULL;
|
||||
SSL_free(m_ssl->m_ssl);
|
||||
m_ssl->m_ssl = NULL;
|
||||
}
|
||||
if (m_ssl->m_context != NULL) {
|
||||
SSL_CTX_free(m_ssl->m_context);
|
||||
m_ssl->m_context = NULL;
|
||||
}
|
||||
delete m_ssl;
|
||||
m_ssl = nullptr;
|
||||
}
|
||||
if (m_ssl->m_context != NULL) {
|
||||
SSL_CTX_free(m_ssl->m_context);
|
||||
m_ssl->m_context = NULL;
|
||||
}
|
||||
delete m_ssl;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@ -40,22 +40,13 @@ ClientListener::ClientListener(const NetworkAddress& address,
|
||||
m_socketFactory(socketFactory),
|
||||
m_server(NULL),
|
||||
m_events(events),
|
||||
m_useSecureNetwork(enableCrypto)
|
||||
m_useSecureNetwork(enableCrypto),
|
||||
m_address(address)
|
||||
{
|
||||
assert(m_socketFactory != NULL);
|
||||
|
||||
try {
|
||||
m_listen = m_socketFactory->createListen(m_useSecureNetwork, ARCH->getAddrFamily(address.getAddress()));
|
||||
|
||||
// setup event handler
|
||||
m_events->adoptHandler(m_events->forIListenSocket().connecting(),
|
||||
m_listen,
|
||||
new TMethodEventJob<ClientListener>(this,
|
||||
&ClientListener::handleClientConnecting));
|
||||
|
||||
// bind listen address
|
||||
LOG((CLOG_DEBUG1 "binding listen socket"));
|
||||
m_listen->bind(address);
|
||||
start();
|
||||
}
|
||||
catch (XSocketAddressInUse&) {
|
||||
cleanupListenSocket();
|
||||
@ -72,31 +63,7 @@ ClientListener::ClientListener(const NetworkAddress& address,
|
||||
|
||||
ClientListener::~ClientListener()
|
||||
{
|
||||
LOG((CLOG_DEBUG1 "stop listening for clients"));
|
||||
|
||||
// discard already connected clients
|
||||
for (NewClients::iterator index = m_newClients.begin();
|
||||
index != m_newClients.end(); ++index) {
|
||||
ClientProxyUnknown* client = *index;
|
||||
m_events->removeHandler(
|
||||
m_events->forClientProxyUnknown().success(), client);
|
||||
m_events->removeHandler(
|
||||
m_events->forClientProxyUnknown().failure(), client);
|
||||
m_events->removeHandler(
|
||||
m_events->forClientProxy().disconnected(), client);
|
||||
delete client;
|
||||
}
|
||||
|
||||
// discard waiting clients
|
||||
ClientProxy* client = getNextClient();
|
||||
while (client != NULL) {
|
||||
delete client;
|
||||
client = getNextClient();
|
||||
}
|
||||
|
||||
m_events->removeHandler(m_events->forIListenSocket().connecting(), m_listen);
|
||||
cleanupListenSocket();
|
||||
cleanupClientSockets();
|
||||
stop();
|
||||
delete m_socketFactory;
|
||||
}
|
||||
|
||||
@ -119,6 +86,56 @@ ClientListener::getNextClient()
|
||||
return client;
|
||||
}
|
||||
|
||||
void ClientListener::start()
|
||||
{
|
||||
m_listen = m_socketFactory->createListen(m_useSecureNetwork, ARCH->getAddrFamily(m_address.getAddress()));
|
||||
|
||||
// setup event handler
|
||||
m_events->adoptHandler(m_events->forIListenSocket().connecting(),
|
||||
m_listen,
|
||||
new TMethodEventJob<ClientListener>(this,
|
||||
&ClientListener::handleClientConnecting));
|
||||
|
||||
// bind listen address
|
||||
LOG((CLOG_DEBUG1 "binding listen socket"));
|
||||
m_listen->bind(m_address);
|
||||
}
|
||||
|
||||
void ClientListener::stop()
|
||||
{
|
||||
LOG((CLOG_DEBUG1 "stop listening for clients"));
|
||||
|
||||
// discard already connected clients
|
||||
for (NewClients::iterator index = m_newClients.begin();
|
||||
index != m_newClients.end(); ++index) {
|
||||
ClientProxyUnknown* client = *index;
|
||||
m_events->removeHandler(
|
||||
m_events->forClientProxyUnknown().success(), client);
|
||||
m_events->removeHandler(
|
||||
m_events->forClientProxyUnknown().failure(), client);
|
||||
m_events->removeHandler(
|
||||
m_events->forClientProxy().disconnected(), client);
|
||||
delete client;
|
||||
}
|
||||
|
||||
// discard waiting clients
|
||||
ClientProxy* client = getNextClient();
|
||||
while (client != nullptr) {
|
||||
delete client;
|
||||
client = getNextClient();
|
||||
}
|
||||
|
||||
m_events->removeHandler(m_events->forIListenSocket().connecting(), m_listen);
|
||||
cleanupListenSocket();
|
||||
cleanupClientSockets();
|
||||
}
|
||||
|
||||
void ClientListener::restart()
|
||||
{
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
|
||||
void
|
||||
ClientListener::handleClientConnecting(const Event&, void*)
|
||||
{
|
||||
|
||||
@ -66,7 +66,10 @@ public:
|
||||
ClientProxy* getNextClient();
|
||||
|
||||
//! Get server which owns this listener
|
||||
Server* getServer() { return m_server; }
|
||||
Server* getServer() { return m_server; }
|
||||
|
||||
//! This method restarts the listener
|
||||
void restart();
|
||||
|
||||
//@}
|
||||
|
||||
@ -79,6 +82,8 @@ private:
|
||||
|
||||
void cleanupListenSocket();
|
||||
void cleanupClientSockets();
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
private:
|
||||
typedef std::set<ClientProxyUnknown*> NewClients;
|
||||
@ -93,4 +98,5 @@ private:
|
||||
IEventQueue* m_events;
|
||||
bool m_useSecureNetwork;
|
||||
ClientSockets m_clientSockets;
|
||||
NetworkAddress m_address;
|
||||
};
|
||||
|
||||
@ -658,6 +658,11 @@ String Config::getClientAddress() const
|
||||
return m_clientAddress;
|
||||
}
|
||||
|
||||
bool Config::isClientMode() const
|
||||
{
|
||||
return (!m_clientAddress.empty());
|
||||
}
|
||||
|
||||
void
|
||||
Config::readSection(ConfigReadContext& s)
|
||||
{
|
||||
|
||||
@ -455,6 +455,13 @@ public:
|
||||
* Return client address a string.
|
||||
*/
|
||||
String getClientAddress() const;
|
||||
|
||||
//! Return true if server started in client mode
|
||||
/*!
|
||||
* In client mode the server initiates connection to client
|
||||
*/
|
||||
bool isClientMode() const;
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
@ -1432,6 +1432,10 @@ Server::handleClientDisconnected(const Event&, void* vclient)
|
||||
removeOldClient(client);
|
||||
|
||||
delete client;
|
||||
|
||||
if (m_args.m_config->isClientMode()) {
|
||||
m_clientListener->restart();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -682,13 +682,12 @@ ServerApp::handleScreenSwitched(const Event& e, void*)
|
||||
ISocketFactory* ServerApp::getSocketFactory() const
|
||||
{
|
||||
ISocketFactory* socketFactory = nullptr;
|
||||
const auto clientAddress = args().m_config->getClientAddress();
|
||||
|
||||
if (clientAddress.empty()) {
|
||||
socketFactory = new TCPSocketFactory(m_events, getSocketMultiplexer());
|
||||
if (args().m_config->isClientMode()) {
|
||||
socketFactory = new InverseSocketFactory(m_events, getSocketMultiplexer());
|
||||
}
|
||||
else {
|
||||
socketFactory = new InverseSocketFactory(m_events, getSocketMultiplexer());
|
||||
socketFactory = new TCPSocketFactory(m_events, getSocketMultiplexer());
|
||||
}
|
||||
|
||||
return socketFactory;
|
||||
@ -696,15 +695,15 @@ ISocketFactory* ServerApp::getSocketFactory() const
|
||||
|
||||
NetworkAddress ServerApp::getAddress(const NetworkAddress& address) const
|
||||
{
|
||||
const auto clientAddress = args().m_config->getClientAddress();
|
||||
if (clientAddress.empty()) {
|
||||
return address;
|
||||
}
|
||||
else {
|
||||
if (args().m_config->isClientMode()) {
|
||||
const auto clientAddress = args().m_config->getClientAddress();
|
||||
NetworkAddress addr(clientAddress.c_str(), kDefaultPort);
|
||||
addr.resolve();
|
||||
return addr;
|
||||
}
|
||||
else {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user