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 Ejemplo de programa servidor. Atiende peticiones aritmeticas, el protocolo de transporte
11 sera el comm::Transport y el contenido del mensaje sera el resutaldo de un comm::Codec con los
12 (x, y, op) -> El resultado sera estos tres componente mas result.
14 Ejemplo de uso del sistema de receiveres, que son capaces de tratar N peticiones de forma
15 totalmetne simultanea en caso de estar en un entorno MT.
17 Para poder probar el sistema de congestion se puede indicar un numero de milisegundos de
18 retardo aplicados a cada contestacion.
20 Los clientes pueden ser: client.p o kclient.p
24 #include <anna/core/core.hpp>
25 #include <anna/comm/comm.hpp>
27 #include <anna/xml/Node.hpp>
28 #include <anna/xml/Attribute.hpp>
30 #include <anna/app/functions.hpp>
32 #include <anna/test/Request.hpp>
33 #include <anna/test/Response.hpp>
34 #include <anna/test/Communicator.hpp>
39 class MyCommunicator : public test::Communicator {
41 MyCommunicator () : test::Communicator () {;}
44 class MyReceiver : public Receiver {
46 virtual ~MyReceiver() {;}
47 static const char* className () throw () { return "MyReceiver"; }
52 MyCommunicator* a_communicator;
54 MyReceiver () : Receiver ("MyReceiver") { ; }
55 void initialize () throw (RuntimeException);
56 void apply (comm::ClientSocket &, const Message&) throw (RuntimeException);
58 friend class Allocator <MyReceiver>;
61 class ArithmeticServer : public comm::Application {
65 comm::DatagramSocket* getOutput () throw () { return a_output; }
68 MyCommunicator* a_communicator;
69 ReceiverFactoryImpl <MyReceiver> a_receiverFactory;
70 comm::DatagramSocket* a_input;
71 comm::DatagramSocket* a_output;
73 void initialize () throw (RuntimeException);
74 void run () throw (RuntimeException);
75 xml::Node* asXML (xml::Node* app) const throw ();
79 using namespace anna::comm;
81 int main (int argc, const char** argv)
83 CommandLine& commandLine (CommandLine::instantiate ());
89 commandLine.initialize (argv, argc);
90 commandLine.verify ();
92 Logger::setLevel (Logger::Debug);
93 Logger::initialize ("arithmeticServer", new TraceWriter ("file.trace",4096000));
97 catch (Exception& ex) {
98 cout << ex.asString () << endl;
104 ArithmeticServer::ArithmeticServer () :
105 Application ("arithmeticServer", "Servidor de operaciones (iRS)", "1.0"),
106 a_communicator (NULL)
108 CommandLine& commandLine (CommandLine::instantiate ());
110 commandLine.add ("as", CommandLine::Argument::Optional, "Direccion broadcast en el que servidor atiende peticiones.");
111 commandLine.add ("ps", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende las peticiones.");
112 commandLine.add ("ac", CommandLine::Argument::Optional, "Direccion broadcast en el que cliente atiende respuestas.");
113 commandLine.add ("pc", CommandLine::Argument::Mandatory, "Puerto al que enviar las respuestas");
114 commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
117 //-----------------------------------------------------------------------------------------
118 // Inicializa el servidor de sockets.
119 //-----------------------------------------------------------------------------------------
120 void ArithmeticServer::initialize ()
121 throw (RuntimeException)
123 CommandLine& cl (CommandLine::instantiate ());
125 const comm::Device* device = Network::instantiate ().find (Device::asAddress (cl.getValue ("as")));
126 int port = cl.getIntegerValue ("ps");
128 a_communicator = new MyCommunicator ();
130 INetAddress localAddress (device, port);
131 a_input = new DatagramSocket (DatagramSocket::ReadOnly, localAddress);
132 a_input->setReceiverFactory (a_receiverFactory);
133 a_communicator->attach (a_input);
135 device = Network::instantiate ().find (Device::asAddress (cl.getValue ("ac")));
136 port = cl.getIntegerValue ("pc");
138 INetAddress remoteAddress (device, port);
139 a_output = new DatagramSocket (DatagramSocket::WriteOnly, remoteAddress);
140 a_output->connect ();
143 //-----------------------------------------------------------------------------------------
144 // Atiende las peticiones.
145 // Cuando hay un nuevo mensaje invocar�a Communicator::eventReceiveMessage
146 //-----------------------------------------------------------------------------------------
147 void ArithmeticServer::run ()
148 throw (RuntimeException)
150 CommandLine& cl (CommandLine::instantiate ());
152 if (cl.exists ("trace"))
153 Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
155 a_communicator->accept ();
158 xml::Node* ArithmeticServer::asXML (xml::Node* app) const
161 xml::Node* node = app::Application::asXML (app);
163 node->createAttribute ("MaxMessage", a_communicator->getMaxMessage ());
164 node->createAttribute ("Message", a_communicator->getMessage ());
169 void MyReceiver::initialize ()
170 throw (RuntimeException)
172 a_communicator = app::functions::component <MyCommunicator> (ANNA_FILE_LOCATION);
175 void MyReceiver::apply (ClientSocket&, const Message& message)
176 throw (RuntimeException)
178 LOGMETHOD (TraceMethod tm ("MyReceiver", "apply", ANNA_FILE_LOCATION));
180 a_request.decode (message.getBody ());
182 a_communicator->delay ();
184 a_response.x = a_request.x;
185 a_response.y = a_request.y;
186 a_response.initTime = a_request.initTime;
188 switch (a_response.op = a_request.op) {
190 a_response.result = a_request.x + a_request.y;
193 a_response.result = a_request.x - a_request.y;
196 a_response.result = a_request.x * a_request.y;
199 a_response.result = (a_request.y != 0) ? (a_request.x / a_request.y): 0;
204 string msg = anna::functions::asString ("%d %c %d = %d", a_request.x, a_request.op, a_request.y, a_response.result);
205 msg += anna::functions::asText (" | InitTime: ", a_response.initTime);
206 Logger::information (msg, ANNA_FILE_LOCATION);
210 static_cast <ArithmeticServer&> (app::functions::getApp ()).getOutput ()->send (a_response);
212 catch (Exception& ex) {