2012-05-29 13:31:11 +00:00
|
|
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Layer 5 and Service example, front-end server.
|
|
|
|
*
|
|
|
|
* This front-end server expects pings, and forward them to
|
|
|
|
* the real ping server. When the ping server sends a pong back,
|
|
|
|
* the front-end server forwards it to the client.
|
|
|
|
*
|
|
|
|
* Even if the connection to the ping server is broken, our
|
|
|
|
* front-end server will keep storing the ping messages and
|
|
|
|
* will forward them when the connection is restored.
|
|
|
|
*
|
|
|
|
* To run this program, ensure there is a file "frontend_service.cfg"
|
|
|
|
* containing the location of the naming service (NSHost, NSPort)
|
|
|
|
* in the working directory. The naming service must be running.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// We're using the NeL Service framework and layer 5.
|
|
|
|
#include "nel/net/service.h"
|
|
|
|
#include "nel/misc/time_nl.h"
|
|
|
|
#include "nel/misc/displayer.h"
|
|
|
|
#include "nel/misc/command.h"
|
|
|
|
#include "nel/misc/hierarchical_timer.h"
|
|
|
|
#include "nel/misc/bit_mem_stream.h"
|
|
|
|
|
|
|
|
#include <deque>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace NLNET;
|
|
|
|
using namespace NLMISC;
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
TTime pingDate;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Callback function called when receiving a "PONG" message
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* - msgin: the incoming message (coming from the ping server)
|
|
|
|
* - from: the "sockid" of the sender (usually useless for a CCallbackClient)
|
|
|
|
* - clientofthepingserver: the CCallbackNetBase object (which really is a CCallbackClient object)
|
|
|
|
*
|
|
|
|
* Input (expected message from the ping server): PONG
|
|
|
|
* - uint32: ping counter
|
|
|
|
* - TSockId: "sock id" of the client who sent the ping
|
|
|
|
*
|
|
|
|
* Output (sent message to a client): PONG
|
|
|
|
* - uint32: ping counter
|
|
|
|
*/
|
|
|
|
void cbPong(CMessage &msgin, const std::string &serviceName, TServiceId sid)
|
|
|
|
{
|
|
|
|
uint32 counter;
|
|
|
|
msgin.serial( counter );
|
|
|
|
TTime pingTime = CTime::getLocalTime()-pingDate;
|
|
|
|
|
|
|
|
nlinfo("Received PONG %u (%u ms)", counter, pingTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sendPing()
|
|
|
|
{
|
|
|
|
pingDate = CTime::getLocalTime();
|
|
|
|
uint32 counter = 0;
|
|
|
|
CMessage msgout("PING");
|
|
|
|
msgout.serial( counter );
|
|
|
|
nlinfo( "Send PING 0");
|
|
|
|
CUnifiedNetwork::getInstance()->send("PS", msgout);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void cbPos(CMessage &msgin, const std::string &serviceName, TServiceId sid)
|
|
|
|
{
|
|
|
|
// decode the message
|
|
|
|
|
|
|
|
TCPUCycle v1 = CTime::getPerformanceTime ();
|
|
|
|
|
|
|
|
uint32 nbid;
|
|
|
|
msgin.serial (nbid);
|
|
|
|
|
|
|
|
for (uint i = 0; i < nbid; i++)
|
|
|
|
{
|
|
|
|
uint64 id;
|
|
|
|
msgin.serial (id);
|
|
|
|
}
|
|
|
|
|
|
|
|
TCPUCycle v2 = CTime::getPerformanceTime ();
|
|
|
|
|
|
|
|
nlinfo("Received POS from %s (serial: %.2fs)", serviceName.c_str(), CTime::ticksToSecond(v2-v1));
|
|
|
|
}
|
|
|
|
|
|
|
|
TTime t = 0;
|
|
|
|
|
|
|
|
void sendRequestVision ()
|
|
|
|
{
|
|
|
|
// nlSleep (1000);
|
|
|
|
CMessage msgout("ASK_VISION");
|
|
|
|
CUnifiedNetwork::getInstance()->send("GPMS", msgout);
|
|
|
|
nlinfo ("ask a new vision");
|
|
|
|
t = CTime::getLocalTime ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void cbVision(CMessage &msgin, const std::string &serviceName, TServiceId sid)
|
|
|
|
{
|
|
|
|
uint32 NbValue;
|
|
|
|
uint32 Value;
|
|
|
|
|
|
|
|
t = CTime::getLocalTime() - t;
|
|
|
|
|
|
|
|
//H_BEFORE (Vision);
|
|
|
|
|
|
|
|
TCPUCycle v1 = CTime::getPerformanceTime ();
|
|
|
|
//H_BEFORE (serial);
|
|
|
|
msgin.serial (NbValue);
|
|
|
|
//H_AFTER (serial);
|
|
|
|
//H_BEFORE (serials);
|
|
|
|
for (uint i = 0; i < NbValue; i++)
|
|
|
|
msgin.serial( Value );
|
|
|
|
//H_AFTER (serials);
|
|
|
|
TCPUCycle v2 = CTime::getPerformanceTime ();
|
|
|
|
|
|
|
|
nlinfo("%dms of lag, Received Vision with %d values in %.2fms", (uint32) t, NbValue, CTime::ticksToSecond (v2-v1)*1000.0f);
|
|
|
|
// sendRequestVision();
|
|
|
|
|
|
|
|
//H_AFTER (Vision);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void sendPos()
|
|
|
|
{
|
|
|
|
nlinfo("Simulate receive pos from client, send POS to GPMS");
|
|
|
|
CMessage msgout("POS");
|
|
|
|
CUnifiedNetwork::getInstance()->send("GPMS", msgout);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void cbUpGPMS(const std::string &serviceName, TServiceId sid, void *arg)
|
|
|
|
{
|
|
|
|
nlinfo( "GPMS connecting.");
|
|
|
|
sendRequestVision ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
void cbUpPS(const std::string &serviceName, TServiceId sid, void *arg)
|
|
|
|
{
|
|
|
|
nlinfo( "Ping Service connecting.");
|
|
|
|
sendPing();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cbDownPS(const std::string &serviceName, TServiceId sid, void *arg)
|
|
|
|
{
|
|
|
|
nlinfo( "Ping Service disconnecting." );
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void cbUpService(const std::string &serviceName, TServiceId sid, void *arg)
|
|
|
|
{
|
|
|
|
nlinfo("Service %s %d is up", serviceName.c_str(), sid.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
void cbDownService(const std::string &serviceName, TServiceId sid, void *arg)
|
|
|
|
{
|
|
|
|
nlinfo("Service %s %d is down", serviceName.c_str(), sid.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Callback array for message received from the ping service
|
|
|
|
*/
|
|
|
|
NLNET::TUnifiedCallbackItem CallbackArray[] =
|
|
|
|
{
|
|
|
|
{ "POS", cbPos },
|
|
|
|
{ "PONG", cbPong },
|
|
|
|
{ "VISION", cbVision }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* CFrontEndService, based on IService
|
|
|
|
*/
|
|
|
|
class CFrontEndService : public NLNET::IService
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
bool update()
|
|
|
|
{
|
|
|
|
static TTime lastPing = CTime::getLocalTime();
|
|
|
|
static TTime lastGetPos = CTime::getLocalTime();
|
|
|
|
|
|
|
|
TTime ctime = CTime::getLocalTime();
|
|
|
|
|
|
|
|
// check vision every 2 seconds
|
|
|
|
if (ctime - lastPing> 2000)
|
|
|
|
{
|
|
|
|
sendRequestVision();
|
|
|
|
lastPing = ctime;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
// check ping every 15 seconds
|
|
|
|
if (ctime - lastPing> 15000)
|
|
|
|
{
|
|
|
|
sendPing();
|
|
|
|
lastPing = ctime;
|
|
|
|
}
|
|
|
|
|
|
|
|
// do as if receive a position every second
|
|
|
|
if (ctime - lastGetPos > 1000)
|
|
|
|
{
|
|
|
|
sendPos();
|
|
|
|
lastGetPos = ctime;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialization
|
|
|
|
*/
|
|
|
|
void init()
|
|
|
|
{
|
|
|
|
/* uint32 u = 0xFFFFFFFF;
|
|
|
|
uint32 z = 0;
|
|
|
|
|
|
|
|
uint32 res = 0;
|
|
|
|
CBitMemStream bms2;
|
|
|
|
|
|
|
|
bms2.serial (u, 1);
|
|
|
|
bms2.serial (z, 18);
|
|
|
|
bms2.serial (u, 4);
|
|
|
|
bms2.serial (z, 3);
|
|
|
|
|
|
|
|
nlinfo ("len %d", bms2.length());
|
|
|
|
bms2.invert ();
|
|
|
|
nlinfo ("len %d", bms2.length());
|
|
|
|
bms2.invert ();
|
|
|
|
nlinfo ("len %d", bms2.length());
|
|
|
|
*/
|
|
|
|
/* CBitMemStream bms;
|
|
|
|
|
|
|
|
nlinfo ("len %d", bms.length());
|
|
|
|
|
|
|
|
bms.serial (u, 1);
|
|
|
|
bms.serial (z, 18);
|
|
|
|
bms.serial (u, 4);
|
|
|
|
bms.serial (z, 3);
|
|
|
|
bms.serial (u, 30);
|
|
|
|
nlinfo ("len %d", bms.length());
|
|
|
|
|
|
|
|
bms.clear ();
|
|
|
|
nlinfo ("len %d", bms.length());
|
|
|
|
|
|
|
|
bms.serial (z, 1);
|
|
|
|
bms.serial (u, 18);
|
|
|
|
bms.serial (z, 4);
|
|
|
|
bms.serial (u, 3);
|
|
|
|
bms.serial (z, 30);
|
|
|
|
nlinfo ("len %d", bms.length());
|
|
|
|
|
|
|
|
|
|
|
|
vector<uint32> cont;
|
|
|
|
for(uint i=0;i<32;i++) cont.push_back(i);
|
|
|
|
bms.serialCont (cont);
|
|
|
|
|
|
|
|
nlinfo ("len %d", bms.length());
|
|
|
|
|
|
|
|
|
|
|
|
bms.invert ();
|
|
|
|
nlinfo ("len %d", bms.length());
|
|
|
|
|
|
|
|
while (bms.getPosInBit() != 30+3+4+18+1)
|
|
|
|
{
|
|
|
|
nlinfo ("%d", bms.getPosInBit());
|
|
|
|
bms.serial (res, 1);
|
|
|
|
nlinfo ((res==0)?"0":"1");
|
|
|
|
}
|
|
|
|
nlinfo ("%d", bms.getPosInBit());
|
|
|
|
|
|
|
|
vector<uint32> cont2;
|
|
|
|
bms.serialCont (cont2);
|
|
|
|
nlinfo ("%d", bms.getPosInBit());
|
|
|
|
for(uint j=0;j<cont2.size();j++) nlinfo ("const %d %d",j, cont2[j]);
|
|
|
|
|
|
|
|
nlinfo ("%d", bms.getPosInBit());
|
|
|
|
*/
|
|
|
|
// Connect to the ping service
|
|
|
|
NLNET::CUnifiedNetwork *instance = NLNET::CUnifiedNetwork::getInstance();
|
|
|
|
|
|
|
|
instance->setServiceUpCallback("PS", cbUpPS, NULL);
|
|
|
|
instance->setServiceDownCallback("PS", cbDownPS, NULL);
|
|
|
|
|
|
|
|
instance->setServiceUpCallback("GPMS", cbUpGPMS, NULL);
|
|
|
|
|
|
|
|
instance->setServiceUpCallback("*", cbUpService, NULL);
|
|
|
|
instance->setServiceDownCallback("*", cbDownService, NULL);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Declare a service with the class CFrontEndService, the names "FS" (short) and "frontend_service" (long).
|
|
|
|
* The port is set to 37000 and the main callback array is CallbackArray.
|
|
|
|
*/
|
|
|
|
NLNET_SERVICE_MAIN( CFrontEndService, "FS", "frontend_service", 37000, CallbackArray, "", "" )
|