X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FServer.hh;h=e33be2cb496cd7eb6516d983b13b5fa8751c85b6;hb=ca70e274a556bf217f3f4c7b12e0fad2a7cd4853;hp=7bca747032fa68d39656411f8868b5d61cfeb4b5;hpb=2d5a1fd2cef2d84e16226a7336948f524fbb71c6;p=senf.git diff --git a/Console/Server.hh b/Console/Server.hh index 7bca747..e33be2c 100644 --- a/Console/Server.hh +++ b/Console/Server.hh @@ -56,6 +56,17 @@ namespace console { \todo Add readline support \todo Add interactivity detection using timeout + \idea To support blocking commands, we could give the Client 'suspend()' and 'resume()' + members. suspend() would probably throw some kind of exception to transfer control back + to the Client instance. on resume(), the command would be called again, maybe setting + some flag or something. Example for use: Host name resolution: Here we can just built + our own little host-name cache. When the name is not found, we ask the resolver to + resolve it and call 'resume' when the name is found. Since it is in the cache now, the + command will now complete. + + \implementation We do \e not provide an \c instance() member so we can easily later extend + the server to allow registering more than one instance, e.g. with each instance on a + differently firewalled port and with different security restrictions. */ class Server : boost::noncopyable @@ -65,10 +76,8 @@ namespace console { public: /////////////////////////////////////////////////////////////////////////// // Types - - typedef senf::ServerSocketHandle< - senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy, - senf::UnspecifiedAddressingPolicy>::policy > ServerHandle; + + typedef detail::ServerHandle ServerHandle; ~Server(); @@ -76,16 +85,19 @@ namespace console { ///< Start server on given IPv4 address/port static Server & start(senf::INet6SocketAddress const & address); ///< Start server on given IPv6 address/port - - void name(std::string const & name); ///< Set server name + Server & name(std::string const & name); ///< Set server name /**< This information is used in the prompt string. */ - + + void stop(); ///< Stop the server + /**< All clients will be closed */ + protected: private: Server(ServerHandle handle); - static void start(ServerHandle handle); + static Server & start(ServerHandle handle); + static boost::scoped_ptr & instancePtr(); void newClient(Scheduler::EventId event); void removeClient(Client & client); @@ -96,8 +108,6 @@ namespace console { Clients clients_; std::string name_; - static boost::scoped_ptr instance_; - friend class Client; }; @@ -106,11 +116,6 @@ namespace console { Whenever a new client connects, a new instance of this class is created. This class shows a command prompt, receives the commands, parses them and then passes (using a CommandParser) and passes the commands to an Executor instance. - - \fixme Fix Client::clientData implementation - \fixme Don't register a new ReadHelper every round - \fixme Ensure, that output errors (or any errors) in the console don't terminate the - application */ class Client : public senf::intrusive_refcount, @@ -121,35 +126,44 @@ namespace console { SENF_LOG_CLASS_AREA(); SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE ); + public: typedef Server::ServerHandle::ClientSocketHandle ClientHandle; ~Client(); - void stopClient(); ///< Stop the client + void stop(); ///< Stop the client /**< This will close the client socket. */ + std::string const & name() const; + ClientHandle handle() const; + std::ostream & stream(); + std::string promptString() const; + + static Client & get(std::ostream & os); + protected: private: - Client(ClientHandle handle, std::string const & name); - - void clientData(ReadHelper::ptr helper); - void showPrompt(); + Client(Server & server, ClientHandle handle, std::string const & name); + void translate(std::string & data); + void handleInput(std::string input); virtual void v_write(boost::posix_time::ptime timestamp, std::string const & stream, std::string const & area, unsigned level, std::string const & message); + Server & server_; ClientHandle handle_; - std::string tail_; CommandParser parser_; Executor executor_; std::string name_; - unsigned promptLen_; std::string lastCommand_; + boost::scoped_ptr reader_; friend class Server; + friend class detail::ClientReader; + friend class detail::NonblockingSocketSink; }; }}