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 using comm::Communicator::eventBreakConnection;
47 test::Response a_response;
48 test::Request a_request;
49 comm::INetAddress a_inetAddress;
50 Recycler <comm::ClientSocket, ClientSocketAllocator> a_clientSockets;
52 void do_initialize () throw (RuntimeException);
54 void eventReceiveMessage (comm::ClientSocket&, const comm::Message&) throw (RuntimeException);
55 void eventBreakConnection (const comm::ClientSocket&) throw ();
56 void eventUser (const char* id, const void* context) throw ();
59 class KXClient : public anna::comm::Application {
63 const test::Menu& getMenu () const throw () { return a_menu; }
66 MyCommunicator a_communicator;
69 void initialize () throw (RuntimeException);
70 void run () throw (RuntimeException);
76 comm::INetAddress* MyCommunicator::ClientSocketAllocator::st_inetAddress = NULL;
78 int main (int argc, const char** argv)
80 CommandLine& commandLine (CommandLine::instantiate ());
84 commandLine.initialize (argv, argc);
85 commandLine.verify ();
87 Logger::setLevel (Logger::Debug);
88 Logger::initialize ("kclient", new TraceWriter ("file.trace", 4096000));
92 catch (Exception& ex) {
93 cout << ex.asString () << endl;
99 KXClient::KXClient () :
100 Application ("kclient", "KXClient", "1.0.0"),
101 a_menu (&a_communicator)
103 CommandLine& commandLine (CommandLine::instantiate ());
105 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
106 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion IP Puerto en el que el servidor atiende respuestas.");
109 void KXClient::initialize ()
110 throw (RuntimeException)
112 a_communicator.attach (&a_menu);
115 void KXClient::run ()
116 throw (RuntimeException)
119 a_communicator.accept ();
122 //--------------------------------------------------------------------------------------------
123 // Crea la direccion a la que se conectaran los ClientSocket para enviar las peticiones.
124 //--------------------------------------------------------------------------------------------
125 void MyCommunicator::do_initialize ()
126 throw (RuntimeException)
128 CommandLine& cl (CommandLine::instantiate ());
130 using namespace anna::comm;
132 Network& network = Network::instantiate ();
134 Device* device = network.find (Device::asAddress (cl.getValue ("a")));
136 a_inetAddress.setAddress (device);
137 a_inetAddress.setPort (cl.getIntegerValue ("p"));
139 ClientSocketAllocator::st_inetAddress = &a_inetAddress;
142 void MyCommunicator::eventReceiveMessage (comm::ClientSocket&, const comm::Message& message)
143 throw (RuntimeException)
145 a_response.decode (message.getBody ());
147 cout << endl << "Resultado de la peticion: " << a_response.x << (char) a_response.op << a_response.y << " = " << a_response.result << endl << endl;
149 static_cast <KXClient&> (anna::comm::functions::getApp ()).getMenu ().paint ();
152 //-----------------------------------------------------------------------------------------
153 // Cuando el servidor remoto cierra el socket => debemos liberar este extremo para poder
154 // reutilizar la instancia (no la conexion).
155 //-----------------------------------------------------------------------------------------
156 void MyCommunicator::eventBreakConnection (const comm::ClientSocket& clientSocket)
159 a_clientSockets.release (&clientSocket);
162 //-----------------------------------------------------------------------------------------
163 // Cuando el Menu tiene disponibles todos los datos necesarios para la peticiĆ³n se lo
164 // notifica al comunicador mediante un evento de usuario.
165 //-----------------------------------------------------------------------------------------
166 void MyCommunicator::eventUser (const char* id, const void* context)
169 LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventUser", ANNA_FILE_LOCATION));
171 if (anna_strcmp (id, Menu::EventData) == 0) {
172 const Menu::Data* data (reinterpret_cast <const Menu::Data*> (context));
174 a_request.op = data->a_operation;
175 a_request.x = data->a_op1;
176 a_request.y = data->a_op2;
178 comm::ClientSocket* clientSocket = a_clientSockets.create ();
181 attach (clientSocket);
182 clientSocket->send (a_request);
184 catch (RuntimeException& ex) {
185 a_clientSockets.release (clientSocket);