1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
10 Establece un manejador externo para controlar el teclado, recoge los parametros de la operacion
11 por este y envia la peticion al servidor que devolvera el resultado de aplicar la operacion
12 sobre los parametros recogidos.
14 Este proceso, a diferencia de kclient, abre una nueva conexion por cada peticion que tiene que lanzar.
16 El cliente de esta aplicacion es: server.p => Transporte: comm::Transport.
22 #include <anna/core/core.hpp>
24 #include <anna/comm/Application.hpp>
25 #include <anna/comm/Communicator.hpp>
26 #include <anna/comm/INetAddress.hpp>
27 #include <anna/comm/ClientSocket.hpp>
28 #include <anna/comm/Network.hpp>
29 #include <anna/comm/Device.hpp>
31 #include <anna/test/Menu.hpp>
32 #include <anna/test/Request.hpp>
33 #include <anna/test/Response.hpp>
35 class MyCommunicator : public comm::Communicator {
37 class ClientSocketAllocator {
39 static comm::INetAddress* st_inetAddress;
40 static comm::ClientSocket* create () throw () { return new comm::ClientSocket (*st_inetAddress); }
41 static void destroy (comm::ClientSocket* clientSocket) throw () { delete clientSocket; }
45 test::Response a_response;
46 test::Request a_request;
47 comm::INetAddress a_inetAddress;
48 Recycler <comm::ClientSocket, ClientSocketAllocator> a_clientSockets;
50 void do_initialize () throw (RuntimeException);
52 void eventReceiveMessage (comm::ClientSocket&, const comm::Message&) throw (RuntimeException);
53 void eventBreakConnection (const comm::ClientSocket&) throw ();
54 void eventUser (const char* id, const void* context) throw ();
57 class KXClient : public anna::comm::Application {
61 const test::Menu& getMenu () const throw () { return a_menu; }
64 MyCommunicator a_communicator;
67 void initialize () throw (RuntimeException);
68 void run () throw (RuntimeException);
74 comm::INetAddress* MyCommunicator::ClientSocketAllocator::st_inetAddress = NULL;
76 int main (int argc, const char** argv)
78 CommandLine& commandLine (CommandLine::instantiate ());
82 commandLine.initialize (argv, argc);
83 commandLine.verify ();
85 Logger::setLevel (Logger::Debug);
86 Logger::initialize ("kclient", new TraceWriter ("file.trace", 4096000));
90 catch (Exception& ex) {
91 cout << ex.asString () << endl;
97 KXClient::KXClient () :
98 Application ("kclient", "KXClient", "1.0.0"),
99 a_menu (&a_communicator)
101 CommandLine& commandLine (CommandLine::instantiate ());
103 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
104 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion IP Puerto en el que el servidor atiende respuestas.");
107 void KXClient::initialize ()
108 throw (RuntimeException)
110 a_communicator.attach (&a_menu);
113 void KXClient::run ()
114 throw (RuntimeException)
117 a_communicator.accept ();
120 //--------------------------------------------------------------------------------------------
121 // Crea la direccion a la que se conectaran los ClientSocket para enviar las peticiones.
122 //--------------------------------------------------------------------------------------------
123 void MyCommunicator::do_initialize ()
124 throw (RuntimeException)
126 CommandLine& cl (CommandLine::instantiate ());
128 using namespace anna::comm;
130 Network& network = Network::instantiate ();
132 Device* device = network.find (Device::asAddress (cl.getValue ("a")));
134 a_inetAddress.setAddress (device);
135 a_inetAddress.setPort (cl.getIntegerValue ("p"));
137 ClientSocketAllocator::st_inetAddress = &a_inetAddress;
140 void MyCommunicator::eventReceiveMessage (comm::ClientSocket&, const comm::Message& message)
141 throw (RuntimeException)
143 a_response.decode (message.getBody ());
145 cout << endl << "Resultado de la peticion: " << a_response.x << (char) a_response.op << a_response.y << " = " << a_response.result << endl << endl;
147 static_cast <KXClient&> (anna::comm::functions::getApp ()).getMenu ().paint ();
150 //-----------------------------------------------------------------------------------------
151 // Cuando el servidor remoto cierra el socket => debemos liberar este extremo para poder
152 // reutilizar la instancia (no la conexion).
153 //-----------------------------------------------------------------------------------------
154 void MyCommunicator::eventBreakConnection (const comm::ClientSocket& clientSocket)
157 a_clientSockets.release (&clientSocket);
160 //-----------------------------------------------------------------------------------------
161 // Cuando el Menu tiene disponibles todos los datos necesarios para la peticiĆ³n se lo
162 // notifica al comunicador mediante un evento de usuario.
163 //-----------------------------------------------------------------------------------------
164 void MyCommunicator::eventUser (const char* id, const void* context)
167 LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventUser", ANNA_FILE_LOCATION));
169 if (anna_strcmp (id, Menu::EventData) == 0) {
170 const Menu::Data* data (reinterpret_cast <const Menu::Data*> (context));
172 a_request.op = data->a_operation;
173 a_request.x = data->a_op1;
174 a_request.y = data->a_op2;
176 comm::ClientSocket* clientSocket = a_clientSockets.create ();
179 attach (clientSocket);
180 clientSocket->send (a_request);
182 catch (RuntimeException& ex) {
183 a_clientSockets.release (clientSocket);