1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
38 Establece un manejador externo para controlar el teclado, recoge los parametros de la operacion
39 por este y envia la peticion al servidor que devolvera el resultado de aplicar la operacion
40 sobre los parametros recogidos.
42 Realiza las peticiones mediante un servicio de reparto por rangos [42, 43]=[+,*],
43 [45, 45]=[-,-] y la division no tiene ningun rango asociado asi que deberia usar el
44 ultimo rango que haya sido establecido.
46 El cliente de esta aplicacion es: server.p rserver.p => Transporte: comm::Transport.
52 #include <anna/core/core.hpp>
53 #include <anna/comm/comm.hpp>
55 #include <anna/test/Menu.hpp>
56 #include <anna/test/Request.hpp>
57 #include <anna/test/Response.hpp>
59 class MyCommunicator : public Communicator {
61 MyCommunicator () : Communicator () {;}
64 test::Response a_response;
65 test::Request a_request;
67 void eventReceiveMessage (ClientSocket&, const Message&) throw (RuntimeException);
68 void eventUser (const char* id, const void* context) throw ();
71 typedef comm::ByRangeDelivery<int> MyService;
73 class BRKClient : public anna::comm::Application {
78 MyService* getService () const throw () { return a_service; }
79 const test::Menu& getMenu () const throw () { return a_menu; }
82 MyCommunicator a_communicator;
86 void initialize () throw (RuntimeException);
87 void run () throw (RuntimeException);
93 int main (int argc, const char** argv)
95 CommandLine& commandLine (CommandLine::instantiate ());
99 commandLine.initialize (argv, argc);
100 commandLine.verify ();
102 Logger::setLevel (Logger::Debug);
103 Logger::initialize ("kclient", new TraceWriter ("file.trace", 4096000));
107 catch (Exception& ex) {
108 cout << ex.asString () << endl;
114 BRKClient::BRKClient () :
115 Application ("kclient", "BRKClient", "1.0.0"),
116 a_menu (&a_communicator)
118 CommandLine& commandLine (CommandLine::instantiate ());
120 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion en el que el servidor atiende respuestas.");
121 commandLine.add ("px", CommandLine::Argument::Mandatory, "Puertos en los que hay servidores de + y *");
122 commandLine.add ("pm", CommandLine::Argument::Mandatory, "Puertos en los que hay servidores de -");
125 void BRKClient::initialize ()
126 throw (RuntimeException)
128 CommandLine& cl (CommandLine::instantiate ());
130 Network& network = Network::instantiate ();
134 MyService::range_iterator rr;
136 const char* ip = cl.getValue ("a");
138 a_service = new MyService ("Service_Arithmetic", true);
140 rr = a_service->createRange ('*', '+');
141 ports.apply (cl.getValue ("px"), ",");
142 for (Tokenizer::const_iterator ii = ports.begin (), maxii = ports.end (); ii != maxii; ii ++) {
143 port = atoi (Tokenizer::data (ii));
144 a_service->attach (rr, network.createServer (ip, port, true));
147 rr = a_service->createRange ('-', '-');
148 ports.apply (cl.getValue ("pm"), ",");
149 for (Tokenizer::const_iterator ii = ports.begin (), maxii = ports.end (); ii != maxii; ii ++) {
150 port = atoi (Tokenizer::data (ii));
151 a_service->attach (rr, network.createServer (ip, port, true));
154 a_communicator.attach (a_service);
155 a_communicator.attach (&a_menu);
158 void BRKClient::run ()
159 throw (RuntimeException)
162 a_communicator.accept ();
165 void MyCommunicator::eventReceiveMessage (ClientSocket&, const Message& message)
166 throw (RuntimeException)
168 a_response.decode (message.getBody ());
170 const Millisecond responseTime = anna::functions::millisecond () - a_response.initTime;
172 cout << endl << "ResponseTime: " << responseTime << " ms" << endl;
173 cout << "Resultado de la peticion: " << a_response.x << (char) a_response.op << a_response.y << " = " << a_response.result << endl << endl;
175 static_cast <BRKClient&> (anna::comm::functions::getApp ()).getMenu ().paint ();
178 //-----------------------------------------------------------------------------------------
179 // Cuando el Menu tiene disponibles todos los datos necesarios para la peticiĆ³n se lo
180 // notifica al comunicador mediante un evento de usuario.
181 //-----------------------------------------------------------------------------------------
182 void MyCommunicator::eventUser (const char* id, const void* context)
185 LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventUser", ANNA_FILE_LOCATION));
187 if (anna_strcmp (id, Menu::EventData) == 0) {
188 const Menu::Data* data (reinterpret_cast <const Menu::Data*> (context));
190 a_request.op = data->a_operation;
191 a_request.x = data->a_op1;
192 a_request.y = data->a_op2;
193 a_request.initTime = anna::functions::millisecond ();
195 MyService* service = static_cast <BRKClient&> (anna::comm::functions::getApp ()).getService ();
198 service->prepare (data->a_operation);
199 service->send (a_request);
201 catch (RuntimeException& ex) {