Allow separate stacks registration through services operation
[anna.git] / example / comm / kClient / main.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 /*
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.
13
14    El cliente de esta aplicacion es: server.p => Transporte: comm::Transport.
15 */
16 #include <iostream>
17
18 #include <string.h>
19
20 #include <anna/core/core.hpp>
21 #include <anna/comm/comm.hpp>
22
23 #include <anna/test/Menu.hpp>
24 #include <anna/test/Request.hpp>
25 #include <anna/test/Response.hpp>
26
27 class MyCommunicator : public Communicator {
28 public:   
29    MyCommunicator () : Communicator () {;}
30    
31 private:
32    test::Response a_response;   
33    test::Request a_request;
34    
35    void eventReceiveMessage (ClientSocket&, const Message&) throw (RuntimeException);
36    void eventUser (const char* id, const void* context) throw ();   
37 };
38
39 class KClient : public anna::comm::Application {
40 public:
41    KClient ();
42       
43    Server* getServer () const throw () { return a_server; }
44    const test::Menu& getMenu () const throw () { return a_menu; }
45    
46 private:
47    MyCommunicator a_communicator;
48    test::Menu a_menu;
49    Server* a_server;
50
51    void initialize () throw (RuntimeException);
52    void run () throw (RuntimeException);    
53 };
54
55 using namespace std;
56 using namespace test;
57
58 int main (int argc, const char** argv)
59 {
60    CommandLine& commandLine (CommandLine::instantiate ());
61    KClient app;
62    
63    try {
64       commandLine.initialize (argv, argc);
65       commandLine.verify ();
66
67       Logger::setLevel (Logger::Debug); 
68       Logger::initialize ("kclient", new TraceWriter ("file.trace", 4096000));
69  
70       app.start ();
71    }
72    catch (Exception& ex) {
73       cout << ex.asString () << endl;
74    }
75    
76    return 0;
77 }
78
79 KClient::KClient () : 
80    Application ("kclient", "KClient", "1.0.0"),
81    a_menu (&a_communicator)
82 {
83    CommandLine& commandLine (CommandLine::instantiate ());
84       
85    commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
86    commandLine.add ("a", CommandLine::Argument::Optional, "Direccion IP Puerto en el que el servidor atiende respuestas.");
87    commandLine.add ("host", CommandLine::Argument::Optional, "Nombre del host en el que atiende el servidor");
88    commandLine.add ("auto", CommandLine::Argument::Optional, "Autoreconexion", false);
89    commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
90
91    activateGeneralPublicLicense ();
92 }
93
94 void KClient::initialize () 
95    throw (RuntimeException)
96 {
97    LOGMETHOD (TraceMethod tm ("MyCommunicator", "initialize", ANNA_FILE_LOCATION));
98
99    CommandLine& cl (CommandLine::instantiate ());    
100
101    Network& network = Network::instantiate ();
102
103   if (cl.exists ("trace"))
104       Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
105
106    const int p = cl.getIntegerValue ("p");
107
108    if (cl.exists ("a"))
109       a_server = network.createServer (cl.getValue ("a"), p, cl.exists ("auto"));
110    else if (cl.exists ("host")) {
111       a_server = network.resolveServer (cl.getValue ("host"), p, cl.exists ("auto"));
112    }
113    else 
114       throw RuntimeException ("Hay que indicar el argumento 'a' o 'host'", ANNA_FILE_LOCATION);
115
116    a_communicator.attach (&a_menu);
117 }
118
119 void KClient::run ()
120    throw (RuntimeException)
121 {   
122    LOGMETHOD (TraceMethod tm ("MyCommunicator", "run", ANNA_FILE_LOCATION));
123
124    a_menu.paint ();
125    a_communicator.accept ();
126 }
127
128 void MyCommunicator::eventReceiveMessage (ClientSocket&, const Message& message)
129    throw (RuntimeException)
130 {
131    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
132
133    a_response.decode (message.getBody ());
134
135    const Millisecond responseTime = (Millisecond)(anna::functions::microsecond()) - a_response.initTime;
136    
137    cout << endl << "ResponseTime: " << responseTime << " us" << endl;
138    cout << "Resultado de la peticion: " << a_response.x << (char) a_response.op << a_response.y  << " = " << a_response.result << endl << endl;
139    
140    static_cast <KClient&> (anna::comm::functions::getApp ()).getMenu ().paint ();
141 }
142
143 //-----------------------------------------------------------------------------------------
144 // Cuando el Menu tiene disponibles todos los datos necesarios para la peticiĆ³n se lo
145 // notifica al comunicador mediante un evento de usuario.
146 //-----------------------------------------------------------------------------------------
147 void MyCommunicator::eventUser (const char* id, const void* context) 
148    throw ()
149 {
150    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventUser", ANNA_FILE_LOCATION));
151
152    if (anna_strcmp (id, Menu::EventData) == 0) {
153       const Menu::Data* data (reinterpret_cast <const Menu::Data*>  (context));
154       
155       a_request.op = data->a_operation;
156       a_request.x = data->a_op1;
157       a_request.y = data->a_op2;
158       a_request.initTime = anna::functions::microsecond ();
159
160       Server* server = static_cast <KClient&> (anna::comm::functions::getApp ()).getServer ();
161       
162       try {
163          server->send (a_request);
164       }
165       catch (RuntimeException& ex) {
166          ex.trace ();
167       }
168    } 
169 }