X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=blobdiff_plain;f=src%2Fcommand_server.cpp;h=cc66de4f58eadd3610eda2dc71d78a1dca9a1333;hp=15a19a75552b449a01785bb9ac3a2732777c56c3;hb=539b09c0c1819f9394e5a0ae8b3df3687715fa7c;hpb=7087e18783f91d2b889e880462d1d1da24831c28 diff --git a/src/command_server.cpp b/src/command_server.cpp index 15a19a7..cc66de4 100644 --- a/src/command_server.cpp +++ b/src/command_server.cpp @@ -20,70 +20,149 @@ #include #include #include +#include #include #include #include #include #include -#include + +#include #include "command_server.hxx" #include "container.hxx" +#include "log.hxx" + +#ifdef HAVE_CONFIG_H +#include +#endif using namespace std; namespace libt2n { +command_server::command_server(server& _s) + : s(_s) +{ + // register callback + s.add_callback(new_connection,bind(&command_server::send_hello, boost::ref(*this), _1)); +} + +void command_server::send_hello(unsigned int conn_id) +{ + server_connection* sc=s.get_connection(conn_id); + + std::ostringstream hello; + + hello << "T2Nv" << PROTOCOL_VERSION << ';'; + + int byteordercheck=1; + hello.write((char*)&byteordercheck,sizeof(byteordercheck)); + + hello << ';'; + + sc->write(hello.str()); +} + /// handle a command including deserialization and answering void command_server::handle_packet(const std::string& packet, server_connection* conn) { + OBJLOGSTREAM(s,debug,"handling packet from connection " << conn->get_id()); + // deserialize packet - istringstream ifs(packet); + std::istringstream ifs(packet); boost::archive::binary_iarchive ia(ifs); command_container ccont; + result_container res; - // TODO: catch - ia >> ccont; + try + { + ia >> ccont; + } + catch(boost::archive::archive_exception &e) + { + std::ostringstream msg; + msg << "archive_exception while deserializing on server-side, " + "code " << e.code << " (" << e.what() << ")"; + res.set_exception(new t2n_serialization_error(msg.str())); + } + catch(...) + { throw; } - // TODO: cast to command subclass (template) - command *cmd=ccont.get_command(); + if (!res.has_exception()) + { + std::ostream* ostr; + if ((ostr=s.get_logstream(fulldebug))!=NULL) + { + (*ostr) << "decoded packet data: " << std::endl; + boost::archive::xml_oarchive xo(*ostr); + xo << BOOST_SERIALIZATION_NVP(ccont); + } - result_container res; + command* cmd=cast_command(ccont.get_command()); - if (cmd) - { - try + if (cmd) + { + try + { + res.set_result((*cmd)()); + } + catch (t2n_exception &e) + { res.set_exception(e.clone()); } + catch (...) + { throw; } + } + else { - res.set_result((*cmd)()); + std::ostringstream msg; + if (ccont.get_command()!=NULL) + msg << "illegal command of type " << typeid(ccont.get_command()).name() << " called"; + else + msg << "NULL command called"; + res.set_exception(new t2n_command_error(msg.str())); } - catch (t2n_exception &e) - { res.set_exception(e.clone()); } - catch (...) - { throw; } } - else - throw logic_error("uninitialized command called"); - ostringstream ofs; + std::ostringstream ofs; boost::archive::binary_oarchive oa(ofs); - // TODO: catch - oa << res; + try + { + oa << res; + } + catch(boost::archive::archive_exception &e) + { + std::ostringstream msg; + msg << "archive_exception while serializing on server-side, " + "code " << e.code << " (" << e.what() << ")"; + res.set_exception(new t2n_serialization_error(msg.str())); + oa << res; + } + catch(...) + { throw; } + + std::ostream* ostr; + if ((ostr=s.get_logstream(fulldebug))!=NULL) + { + (*ostr) << "returning result, decoded data: " << std::endl; + boost::archive::xml_oarchive xo(*ostr); + xo << BOOST_SERIALIZATION_NVP(res); + } conn->write(ofs.str()); } /** @brief handle incoming commands - @param usec_timeout wait until new data is found, max timeout usecs. - -1: wait endless, 0: no timeout + @param[in,out] usec_timeout wait until new data is found, max timeout usecs. + -1: wait endless, 0: instant return */ -void command_server::handle(long long usec_timeout) +void command_server::handle(long long usec_timeout, long long* usec_timeout_remaining) { - if (s.fill_buffer(usec_timeout)) + if (s.fill_buffer(usec_timeout,usec_timeout_remaining)) { - string packet; + std::string packet; unsigned int conn_id; while (s.get_packet(packet,conn_id))