#ifndef __ServerConnection_h_ #define __ServerConnection_h_ #include "TalkWithServer.h" #include "ContainerThread.h" /* The bulk of the activity should be confined to the ContainerThread. The * constructor and destructor can be called elsewhere. Just make sure no one * is still accessing the object when you call the destructor. */ class ServerConnection : public IContainerThreadUser, protected TalkWithServer::IMessageListener { private: static const int CI_PING = -1; const std::string _name; TalkWithServer *_talkWithServer; time_t _nextPingTime; time_t _connectionBlackout; bool _pingSent; void checkPing(); protected: // From TalkWithServer::IMessageListener virtual void onMessage(std::string bytes, int clientId, TalkWithServer::CancelId cancelId); virtual void onAbort(int clientId, TalkWithServer::CancelId cancelId); // From IContainerThreadUser virtual void beforeSleep(IBeforeSleepCallbacks &callbacks); virtual void awake(std::set< int > const &woken); // New virtual void onNewConnection(TalkWithServer *talkWithServer); virtual bool shouldTryToConnect(); virtual std::string getServerName() =0; virtual std::string getServerPort() =0; TalkWithServer *getConnection(bool createIfRequired=true); std::string const &getName() const { return _name; } ServerConnection(std::string const &name); // This will NOT call the callbacks for any outstanding requests. Pesumably // the callbacks would go to this object (possibly in a subclass, which has // already called it's destructor). Also, it's not clear which thread we'll // be in when the destructor is called. ~ServerConnection(); public: }; /* This is very similar to ServerConnection but it fixed a few rough edges. * This is slightly less powerful, but I'm not sure if anyone really needs the * extra power. * * FeedServer was built directly on top of ServerConnection. This allows a * FeedServer object to be destroyed. That, of course, makes FeedServer a * more powerful class, but it was more complicted to build. I'm not sure * if there's any good reason FeedServer needed this ability. I recommend * ForeverServerConnection for all new development. * * The most obvious difference between ForeverServerConnection and * ServerConnection is that you can't destory a ForeverServerConnection * object. It's as if ForeverServerConnection inherited from ForeverThreadUser * rather than IContainerThreadUser. (In fact, I had to copy some code, * rather than using inheritance, but that's an implementation detail.) * * I also made _serverName and _serverPort into variables. You don't lose * much. You could have computed / recomputed these exactly when they were * needed. In fact, you still can. Just override getServerName() and/or * getServerPort() again! */ class ForeverServerConnection : public ServerConnection, public RequestListener { protected: const Ref _keepMeAlive; void start() { getContainer()->addUser(_keepMeAlive); } // For RequestListener. virtual void newRequest(Request *request) { returnToMe(_keepMeAlive, request); } std::string _serverName; std::string _serverPort; // For ServerConnection. virtual std::string getServerName() { return _serverName; } // For ServerConnection. virtual std::string getServerPort() { return _serverPort; } // For ServerConnection. virtual bool shouldTryToConnect(); bool getAndParseAddress(std::string const &configName); ForeverServerConnection(std::string const &name) : ServerConnection(name), _keepMeAlive(this) { } }; #endif