1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * Layer 5 and Service example, front-end server.
21 * This front-end server expects pings, and forward them to
22 * the real ping server. When the ping server sends a pong back,
23 * the front-end server forwards it to the client.
25 * Even if the connection to the ping server is broken, our
26 * front-end server will keep storing the ping messages and
27 * will forward them when the connection is restored.
29 * To run this program, ensure there is a file "frontend_service.cfg"
30 * containing the location of the naming service (NSHost, NSPort)
31 * in the working directory. The naming service must be running.
35 // We're using the NeL Service framework and layer 5.
36 #include "nel/net/service.h"
37 #include "nel/misc/time_nl.h"
38 #include "nel/misc/displayer.h"
39 #include "nel/misc/command.h"
40 #include "nel/misc/hierarchical_timer.h"
41 #include "nel/misc/bit_mem_stream.h"
46 using namespace NLNET
;
47 using namespace NLMISC
;
54 * Callback function called when receiving a "PONG" message
57 * - msgin: the incoming message (coming from the ping server)
58 * - from: the "sockid" of the sender (usually useless for a CCallbackClient)
59 * - clientofthepingserver: the CCallbackNetBase object (which really is a CCallbackClient object)
61 * Input (expected message from the ping server): PONG
62 * - uint32: ping counter
63 * - TSockId: "sock id" of the client who sent the ping
65 * Output (sent message to a client): PONG
66 * - uint32: ping counter
68 void cbPong(CMessage
&msgin
, const std::string
&serviceName
, TServiceId sid
)
71 msgin
.serial( counter
);
72 TTime pingTime
= CTime::getLocalTime()-pingDate
;
74 nlinfo("Received PONG %u (%u ms)", counter
, pingTime
);
79 pingDate
= CTime::getLocalTime();
81 CMessage
msgout("PING");
82 msgout
.serial( counter
);
83 nlinfo( "Send PING 0");
84 CUnifiedNetwork::getInstance()->send("PS", msgout
);
88 void cbPos(CMessage
&msgin
, const std::string
&serviceName
, TServiceId sid
)
92 TCPUCycle v1
= CTime::getPerformanceTime ();
97 for (uint i
= 0; i
< nbid
; i
++)
103 TCPUCycle v2
= CTime::getPerformanceTime ();
105 nlinfo("Received POS from %s (serial: %.2fs)", serviceName
.c_str(), CTime::ticksToSecond(v2
-v1
));
110 void sendRequestVision ()
113 CMessage
msgout("ASK_VISION");
114 CUnifiedNetwork::getInstance()->send("GPMS", msgout
);
115 nlinfo ("ask a new vision");
116 t
= CTime::getLocalTime ();
119 void cbVision(CMessage
&msgin
, const std::string
&serviceName
, TServiceId sid
)
124 t
= CTime::getLocalTime() - t
;
128 TCPUCycle v1
= CTime::getPerformanceTime ();
130 msgin
.serial (NbValue
);
132 //H_BEFORE (serials);
133 for (uint i
= 0; i
< NbValue
; i
++)
134 msgin
.serial( Value
);
136 TCPUCycle v2
= CTime::getPerformanceTime ();
138 nlinfo("%dms of lag, Received Vision with %d values in %.2fms", (uint32
) t
, NbValue
, CTime::ticksToSecond (v2
-v1
)*1000.0f
);
139 // sendRequestVision();
147 nlinfo("Simulate receive pos from client, send POS to GPMS");
148 CMessage
msgout("POS");
149 CUnifiedNetwork::getInstance()->send("GPMS", msgout
);
153 void cbUpGPMS(const std::string
&serviceName
, TServiceId sid
, void *arg
)
155 nlinfo( "GPMS connecting.");
156 sendRequestVision ();
161 void cbUpPS(const std::string
&serviceName
, TServiceId sid
, void *arg
)
163 nlinfo( "Ping Service connecting.");
168 void cbDownPS(const std::string
&serviceName
, TServiceId sid
, void *arg
)
170 nlinfo( "Ping Service disconnecting." );
174 void cbUpService(const std::string
&serviceName
, TServiceId sid
, void *arg
)
176 nlinfo("Service %s %d is up", serviceName
.c_str(), sid
.get());
179 void cbDownService(const std::string
&serviceName
, TServiceId sid
, void *arg
)
181 nlinfo("Service %s %d is down", serviceName
.c_str(), sid
.get());
186 * Callback array for message received from the ping service
188 NLNET::TUnifiedCallbackItem CallbackArray
[] =
192 { "VISION", cbVision
}
197 * CFrontEndService, based on IService
199 class CFrontEndService
: public NLNET::IService
205 static TTime lastPing
= CTime::getLocalTime();
206 static TTime lastGetPos
= CTime::getLocalTime();
208 TTime ctime
= CTime::getLocalTime();
210 // check vision every 2 seconds
211 if (ctime
- lastPing
> 2000)
218 // check ping every 15 seconds
219 if (ctime - lastPing> 15000)
225 // do as if receive a position every second
226 if (ctime - lastGetPos > 1000)
240 /* uint32 u = 0xFFFFFFFF;
251 nlinfo ("len %d", bms2.length());
253 nlinfo ("len %d", bms2.length());
255 nlinfo ("len %d", bms2.length());
257 /* CBitMemStream bms;
259 nlinfo ("len %d", bms.length());
266 nlinfo ("len %d", bms.length());
269 nlinfo ("len %d", bms.length());
276 nlinfo ("len %d", bms.length());
280 for(uint i=0;i<32;i++) cont.push_back(i);
281 bms.serialCont (cont);
283 nlinfo ("len %d", bms.length());
287 nlinfo ("len %d", bms.length());
289 while (bms.getPosInBit() != 30+3+4+18+1)
291 nlinfo ("%d", bms.getPosInBit());
293 nlinfo ((res==0)?"0":"1");
295 nlinfo ("%d", bms.getPosInBit());
297 vector<uint32> cont2;
298 bms.serialCont (cont2);
299 nlinfo ("%d", bms.getPosInBit());
300 for(uint j=0;j<cont2.size();j++) nlinfo ("const %d %d",j, cont2[j]);
302 nlinfo ("%d", bms.getPosInBit());
304 // Connect to the ping service
305 NLNET::CUnifiedNetwork
*instance
= NLNET::CUnifiedNetwork::getInstance();
307 instance
->setServiceUpCallback("PS", cbUpPS
, NULL
);
308 instance
->setServiceDownCallback("PS", cbDownPS
, NULL
);
310 instance
->setServiceUpCallback("GPMS", cbUpGPMS
, NULL
);
312 instance
->setServiceUpCallback("*", cbUpService
, NULL
);
313 instance
->setServiceDownCallback("*", cbDownService
, NULL
);
318 * Declare a service with the class CFrontEndService, the names "FS" (short) and "frontend_service" (long).
319 * The port is set to 37000 and the main callback array is CallbackArray.
321 NLNET_SERVICE_MAIN( CFrontEndService
, "FS", "frontend_service", 37000, CallbackArray
, "", "" )