added support for camping, i.e. repeatly trying to connect to the

server until we succeed.
This commit is contained in:
crs 2002-06-09 22:20:28 +00:00
parent 30a6a8b837
commit 28afcddf62
3 changed files with 79 additions and 15 deletions

View File

@ -33,6 +33,7 @@ CClient::CClient(const CString& clientName) :
m_input(NULL), m_input(NULL),
m_output(NULL), m_output(NULL),
m_screen(NULL), m_screen(NULL),
m_camp(false),
m_active(false), m_active(false),
m_seqNum(0), m_seqNum(0),
m_ignoreMove(false) m_ignoreMove(false)
@ -45,7 +46,12 @@ CClient::~CClient()
// do nothing // do nothing
} }
void CClient::run(const CNetworkAddress& serverAddress) void CClient::camp(bool on)
{
m_camp = on;
}
bool CClient::run(const CNetworkAddress& serverAddress)
{ {
CThread* thread = NULL; CThread* thread = NULL;
try { try {
@ -74,9 +80,10 @@ void CClient::run(const CNetworkAddress& serverAddress)
// clean up // clean up
log((CLOG_NOTE "stopping client")); log((CLOG_NOTE "stopping client"));
thread->cancel(); thread->cancel();
thread->wait(); void* result = thread->getResult();
delete thread; delete thread;
closeSecondaryScreen(); closeSecondaryScreen();
return (result != NULL);
} }
catch (XBase& e) { catch (XBase& e) {
log((CLOG_ERR "client error: %s", e.what())); log((CLOG_ERR "client error: %s", e.what()));
@ -89,6 +96,7 @@ void CClient::run(const CNetworkAddress& serverAddress)
delete thread; delete thread;
} }
closeSecondaryScreen(); closeSecondaryScreen();
return true;
} }
catch (XThread&) { catch (XThread&) {
// clean up // clean up
@ -183,14 +191,29 @@ void CClient::runSession(void*)
std::auto_ptr<IInputStream> input; std::auto_ptr<IInputStream> input;
std::auto_ptr<IOutputStream> output; std::auto_ptr<IOutputStream> output;
try { try {
// allow connect this much time to succeed for (;;) {
CTimerThread timer(30.0); // FIXME -- timeout in member try {
// allow connect this much time to succeed
// FIXME -- timeout in member
CTimerThread timer(m_camp ? -1.0 : 30.0);
// create socket and attempt to connect to server // create socket and attempt to connect to server
log((CLOG_DEBUG1 "connecting to server")); log((CLOG_DEBUG1 "connecting to server"));
assign(socket, new CTCPSocket(), ISocket); // FIXME -- use factory assign(socket, new CTCPSocket(), ISocket); // FIXME -- use factory
socket->connect(*m_serverAddress); socket->connect(*m_serverAddress);
log((CLOG_INFO "connected to server")); log((CLOG_INFO "connected to server"));
break;
}
catch (XSocketConnect&) {
// failed to connect. if not camping then rethrow.
if (!m_camp) {
throw;
}
// we're camping. wait a bit before retrying
CThread::sleep(5.0);
}
}
// get the input and output streams // get the input and output streams
IInputStream* srcInput = socket->getInputStream(); IInputStream* srcInput = socket->getInputStream();
@ -208,6 +231,9 @@ void CClient::runSession(void*)
} }
*/ */
// give handshake some time
CTimerThread timer(30.0);
// attach the packetizing filters // attach the packetizing filters
assign(input, new CInputPacketStream(srcInput, own), IInputStream); assign(input, new CInputPacketStream(srcInput, own), IInputStream);
assign(output, new COutputPacketStream(srcOutput, own), IOutputStream); assign(output, new COutputPacketStream(srcOutput, own), IOutputStream);
@ -238,7 +264,7 @@ void CClient::runSession(void*)
catch (XIncompatibleClient& e) { catch (XIncompatibleClient& e) {
log((CLOG_ERR "server has incompatible version %d.%d", e.getMajor(), e.getMinor())); log((CLOG_ERR "server has incompatible version %d.%d", e.getMajor(), e.getMinor()));
m_screen->stop(); m_screen->stop();
return; CThread::exit(NULL);
} }
catch (XThread&) { catch (XThread&) {
log((CLOG_ERR "connection timed out")); log((CLOG_ERR "connection timed out"));
@ -248,7 +274,12 @@ void CClient::runSession(void*)
catch (XBase& e) { catch (XBase& e) {
log((CLOG_ERR "connection failed: %s", e.what())); log((CLOG_ERR "connection failed: %s", e.what()));
m_screen->stop(); m_screen->stop();
return; CThread::exit(NULL);
}
catch (...) {
log((CLOG_ERR "connection failed: <unknown error>"));
m_screen->stop();
CThread::exit(NULL);
} }
try { try {
@ -346,7 +377,7 @@ void CClient::runSession(void*)
catch (XBase& e) { catch (XBase& e) {
log((CLOG_ERR "error: %s", e.what())); log((CLOG_ERR "error: %s", e.what()));
m_screen->stop(); m_screen->stop();
return; CThread::exit(reinterpret_cast<void*>(1));
} }
// done with socket // done with socket
@ -355,6 +386,8 @@ void CClient::runSession(void*)
// exit event loop // exit event loop
m_screen->stop(); m_screen->stop();
CThread::exit(reinterpret_cast<void*>(1));
} }
// FIXME -- use factory to create screen // FIXME -- use factory to create screen

View File

@ -19,8 +19,17 @@ public:
// manipulators // manipulators
// turn camping on or off. when camping the client will keep
// trying to connect to the server until it succeeds. this
// is useful if the client may start before the server. do
// not call this while in run().
void camp(bool on);
// start the client. does not return until quit() is called. // start the client. does not return until quit() is called.
void run(const CNetworkAddress& serverAddress); // returns true if the client ever connected to the server
// successfully. may also throw exceptions after successfully
// connecting.
bool run(const CNetworkAddress& serverAddress);
// tell client to exit gracefully // tell client to exit gracefully
void quit(); void quit();
@ -67,6 +76,7 @@ private:
IOutputStream* m_output; IOutputStream* m_output;
ISecondaryScreen* m_screen; ISecondaryScreen* m_screen;
const CNetworkAddress* m_serverAddress; const CNetworkAddress* m_serverAddress;
bool m_camp;
bool m_active; bool m_active;
UInt32 m_seqNum; UInt32 m_seqNum;
bool m_ignoreMove; bool m_ignoreMove;

View File

@ -29,6 +29,7 @@
static const char* pname = NULL; static const char* pname = NULL;
static bool s_restartable = true; static bool s_restartable = true;
static bool s_daemon = true; static bool s_daemon = true;
static bool s_camp = true;
static bool s_install = false; static bool s_install = false;
static bool s_uninstall = false; static bool s_uninstall = false;
static const char* s_logFilter = NULL; static const char* s_logFilter = NULL;
@ -76,13 +77,14 @@ static int realMain(CMutex* mutex)
try { try {
// create client // create client
s_client = new CClient(s_name); s_client = new CClient(s_name);
s_client->camp(s_camp);
// run client // run client
if (mutex != NULL) { if (mutex != NULL) {
mutex->unlock(); mutex->unlock();
} }
locked = false; locked = false;
s_client->run(s_serverAddress); bool success = s_client->run(s_serverAddress);
locked = true; locked = true;
if (mutex != NULL) { if (mutex != NULL) {
mutex->lock(); mutex->lock();
@ -94,6 +96,8 @@ static int realMain(CMutex* mutex)
CNetwork::cleanup(); CNetwork::cleanup();
CLog::setLock(NULL); CLog::setLock(NULL);
s_logMutex = NULL; s_logMutex = NULL;
return success ? 16 : 0;
} }
catch (...) { catch (...) {
// clean up // clean up
@ -166,6 +170,7 @@ static void help()
log((CLOG_PRINT log((CLOG_PRINT
"Usage: %s" "Usage: %s"
" [--"DAEMON"|--no-"DAEMON"]" " [--"DAEMON"|--no-"DAEMON"]"
" [--camp|--no-camp]"
" [--debug <level>]" " [--debug <level>]"
" [--name <screen-name>]" " [--name <screen-name>]"
" [--restart|--no-restart]" " [--restart|--no-restart]"
@ -175,6 +180,9 @@ static void help()
" --uninstall\n" " --uninstall\n"
"Start the synergy mouse/keyboard sharing server.\n" "Start the synergy mouse/keyboard sharing server.\n"
"\n" "\n"
"* --camp keep attempting to connect to the server until\n"
" successful.\n"
" --no-camp do not camp.\n"
" -d, --debug <level> filter out log messages with priorty below level.\n" " -d, --debug <level> filter out log messages with priorty below level.\n"
" level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n" " level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n"
" DEBUG, DEBUG1, DEBUG2.\n" " DEBUG, DEBUG1, DEBUG2.\n"
@ -184,7 +192,10 @@ static void help()
" ourself to the server.\n" " ourself to the server.\n"
" -1, --no-restart do not try to restart the client if it fails for\n" " -1, --no-restart do not try to restart the client if it fails for\n"
" some reason.\n" " some reason.\n"
"* --restart restart the client automatically if it fails.\n" "* --restart restart the client automatically if it fails for\n"
" some unexpected reason, including the server\n"
" disconnecting but not including failing to\n"
" connect to the server."
" --install install server as a "DAEMON".\n" " --install install server as a "DAEMON".\n"
" --uninstall uninstall server "DAEMON".\n" " --uninstall uninstall server "DAEMON".\n"
" -h, --help display this help and exit.\n" " -h, --help display this help and exit.\n"
@ -248,6 +259,16 @@ static void parse(int argc, const char** argv)
s_name = argv[++i]; s_name = argv[++i];
} }
else if (isArg(i, argc, argv, NULL, "--camp")) {
// enable camping
s_camp = true;
}
else if (isArg(i, argc, argv, NULL, "--no-camp")) {
// disable camping
s_camp = false;
}
else if (isArg(i, argc, argv, "-f", "--no-"DAEMON)) { else if (isArg(i, argc, argv, "-f", "--no-"DAEMON)) {
// not a daemon // not a daemon
s_daemon = false; s_daemon = false;