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 static const char* className () throw () { return "MyReceiver"; }
51 MyCommunicator* a_communicator;
53 MyReceiver () : Receiver ("MyReceiver") { ; }
54 void initialize () throw (RuntimeException);
55 void apply (comm::ClientSocket &, const Message&) throw (RuntimeException);
57 friend class Allocator <MyReceiver>;
60 class ArithmeticServer : public comm::Application {
64 comm::DatagramSocket* getOutput () throw () { return a_output; }
67 MyCommunicator* a_communicator;
68 ReceiverFactoryImpl <MyReceiver> a_receiverFactory;
69 comm::DatagramSocket* a_input;
70 comm::DatagramSocket* a_output;
72 void initialize () throw (RuntimeException);
73 void run () throw (RuntimeException);
74 xml::Node* asXML (xml::Node* app) const throw ();
78 using namespace anna::comm;
80 int main (int argc, const char** argv)
82 CommandLine& commandLine (CommandLine::instantiate ());
88 commandLine.initialize (argv, argc);
89 commandLine.verify ();
91 Logger::setLevel (Logger::Debug);
92 Logger::initialize ("arithmeticServer", new TraceWriter ("file.trace",4096000));
96 catch (Exception& ex) {
97 cout << ex.asString () << endl;
103 ArithmeticServer::ArithmeticServer () :
104 Application ("arithmeticServer", "Servidor de operaciones (iRS)", "1.0"),
105 a_communicator (NULL)
107 CommandLine& commandLine (CommandLine::instantiate ());
109 commandLine.add ("as", CommandLine::Argument::Optional, "Direccion broadcast en el que servidor atiende peticiones.");
110 commandLine.add ("ps", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende las peticiones.");
111 commandLine.add ("ac", CommandLine::Argument::Optional, "Direccion broadcast en el que cliente atiende respuestas.");
112 commandLine.add ("pc", CommandLine::Argument::Mandatory, "Puerto al que enviar las respuestas");
113 commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
116 //-----------------------------------------------------------------------------------------
117 // Inicializa el servidor de sockets.
118 //-----------------------------------------------------------------------------------------
119 void ArithmeticServer::initialize ()
120 throw (RuntimeException)
122 CommandLine& cl (CommandLine::instantiate ());
124 const comm::Device* device = Network::instantiate ().find (Device::asAddress (cl.getValue ("as")));
125 int port = cl.getIntegerValue ("ps");
127 a_communicator = new MyCommunicator ();
129 INetAddress localAddress (device, port);
130 a_input = new DatagramSocket (DatagramSocket::ReadOnly, localAddress);
131 a_input->setReceiverFactory (a_receiverFactory);
132 a_communicator->attach (a_input);
134 device = Network::instantiate ().find (Device::asAddress (cl.getValue ("ac")));
135 port = cl.getIntegerValue ("pc");
137 INetAddress remoteAddress (device, port);
138 a_output = new DatagramSocket (DatagramSocket::WriteOnly, remoteAddress);
139 a_output->connect ();
142 //-----------------------------------------------------------------------------------------
143 // Atiende las peticiones.
144 // Cuando hay un nuevo mensaje invocar�a Communicator::eventReceiveMessage
145 //-----------------------------------------------------------------------------------------
146 void ArithmeticServer::run ()
147 throw (RuntimeException)
149 CommandLine& cl (CommandLine::instantiate ());
151 if (cl.exists ("trace"))
152 Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
154 a_communicator->accept ();
157 xml::Node* ArithmeticServer::asXML (xml::Node* app) const
160 xml::Node* node = app::Application::asXML (app);
162 node->createAttribute ("MaxMessage", a_communicator->getMaxMessage ());
163 node->createAttribute ("Message", a_communicator->getMessage ());
168 void MyReceiver::initialize ()
169 throw (RuntimeException)
171 a_communicator = app::functions::component <MyCommunicator> (ANNA_FILE_LOCATION);
174 void MyReceiver::apply (ClientSocket&, const Message& message)
175 throw (RuntimeException)
177 LOGMETHOD (TraceMethod tm ("MyReceiver", "apply", ANNA_FILE_LOCATION));
179 a_request.decode (message.getBody ());
181 a_communicator->delay ();
183 a_response.x = a_request.x;
184 a_response.y = a_request.y;
185 a_response.initTime = a_request.initTime;
187 switch (a_response.op = a_request.op) {
189 a_response.result = a_request.x + a_request.y;
192 a_response.result = a_request.x - a_request.y;
195 a_response.result = a_request.x * a_request.y;
198 a_response.result = (a_request.y != 0) ? (a_request.x / a_request.y): 0;
203 string msg = anna::functions::asString ("%d %c %d = %d", a_request.x, a_request.op, a_request.y, a_response.result);
204 msg += anna::functions::asText (" | InitTime: ", a_response.initTime);
205 Logger::information (msg, ANNA_FILE_LOCATION);
209 static_cast <ArithmeticServer&> (app::functions::getApp ()).getOutput ()->send (a_response);
211 catch (Exception& ex) {