Remove dynamic exceptions
[anna.git] / example / comm / rrkClient / 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: service.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&) noexcept(false);
36    void eventUser (const char* id, const void* context) ;   
37 };
38
39 class RRKClient : public anna::comm::Application {
40 public:
41    RRKClient ();
42       
43    Service* getService () const { return a_service; }
44    const test::Menu& getMenu () const { return a_menu; }
45    
46 private:
47    MyCommunicator a_communicator;
48    test::Menu a_menu;
49    Service* a_service;
50
51    void initialize () noexcept(false);
52    void run () noexcept(false);    
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    RRKClient 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 RRKClient::RRKClient () : 
80    Application ("kclient", "RRKClient", "1.0.0"),
81    a_menu (&a_communicator)
82 {
83    CommandLine& commandLine (CommandLine::instantiate ());
84       
85    commandLine.add ("p", CommandLine::Argument::Mandatory, "Puertos en los que el servidor atiende respuestas.");
86    commandLine.add ("a", CommandLine::Argument::Mandatory, "Puertos en los que hay servidores atendiendo peticiones");
87    commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
88 }
89
90 void RRKClient::initialize () 
91    noexcept(false)
92 {
93    CommandLine& cl (CommandLine::instantiate ());    
94
95    if (cl.exists ("trace"))
96       Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
97
98    Network& network = Network::instantiate ();
99
100    Tokenizer ports (cl.getValue ("p"), ",");
101    int port;
102
103    a_service = new comm::RoundRobinDelivery ("Service_Arithmetic", true);
104
105    for (Tokenizer::const_iterator ii = ports.begin (), maxii = ports.end (); ii != maxii; ii ++) {
106       port = atoi (Tokenizer::data (ii));
107       a_service->attach (network.createServer (cl.getValue ("a"), port, true));
108    }
109
110    a_communicator.attach (a_service);
111    a_communicator.attach (&a_menu);
112 }
113
114 void RRKClient::run ()
115    noexcept(false)
116 {   
117    a_menu.paint ();
118    a_communicator.accept ();
119 }
120
121 void MyCommunicator::eventReceiveMessage (ClientSocket&, const Message& message)
122    noexcept(false)
123 {
124    LOGMETHOD (TraceMethod tm (Logger::Local7, "MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
125
126    a_response.decode (message.getBody ());
127
128    const Millisecond responseTime = anna::functions::millisecond () - a_response.initTime;
129    
130    cout << endl << "ResponseTime: " << responseTime << " ms" << endl;
131    cout << "Resultado de la peticion: " << a_response.x << (char) a_response.op << a_response.y  << " = " << a_response.result << endl << endl;
132    
133    static_cast <RRKClient&> (anna::comm::functions::getApp ()).getMenu ().paint ();
134 }
135
136 //-----------------------------------------------------------------------------------------
137 // Cuando el Menu tiene disponibles todos los datos necesarios para la peticiĆ³n se lo
138 // notifica al comunicador mediante un evento de usuario.
139 //-----------------------------------------------------------------------------------------
140 void MyCommunicator::eventUser (const char* id, const void* context) 
141    
142 {
143    LOGMETHOD (TraceMethod tm (Logger::Local7, "MyCommunicator", "eventUser", ANNA_FILE_LOCATION));
144
145    if (anna_strcmp (id, Menu::EventData) == 0) {
146       const Menu::Data* data (reinterpret_cast <const Menu::Data*>  (context));
147       
148       a_request.op = data->a_operation;
149       a_request.x = data->a_op1;
150       a_request.y = data->a_op2;
151       a_request.initTime = anna::functions::millisecond ();
152       
153       Service* service = static_cast <RRKClient&> (anna::comm::functions::getApp ()).getService ();
154       
155       try {
156          service->send (a_request);
157       }
158       catch (RuntimeException& ex) {
159          ex.trace ();
160       }
161    } 
162 }
163