khanat-opennel-code/code/nel/samples/net/net_layer5/gpm_service.cpp

257 lines
6 KiB
C++

// 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 4 and Service example, ping server.
*
* This ping service expects pings, sends pongs back.
*
* To run this program, ensure there is a file "ping_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"
using namespace std;
using namespace NLNET;
using namespace NLMISC;
uint32 NbId = 0;
//
TTime pingDate;
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)
{
CMessage msgout("ACK_POS");
CUnifiedNetwork::getInstance()->send("PLS", msgout);
TCPUCycle v1 = CTime::getPerformanceTime ();
CMessage msgoutfe("POS", false, CMessage::UseDefault, NbId*8);
uint64 id = rand();
msgoutfe.serial (NbId);
for (uint i = 0; i < NbId; i++)
{
msgoutfe.serial (id);
id++;
}
TCPUCycle v2 = CTime::getPerformanceTime ();
CUnifiedNetwork::getInstance()->send("FS", msgoutfe);
TCPUCycle v3 = CTime::getPerformanceTime ();
nlinfo( "Received POS, Sending POS to FS (serial %.2fs, send %.2fs)", CTime::ticksToSecond (v2-v1), CTime::ticksToSecond (v3-v2));
}
void cbAskVision(CMessage &msgin, const std::string &serviceName, TServiceId sid)
{
uint32 Value = '0ACE';
// H_BEFORE (Vision);
TCPUCycle v1 = CTime::getPerformanceTime ();
// H_BEFORE (CMessage);
CMessage msgout("VISION", false, CMessage::UseDefault, 10000000);
// H_AFTER (CMessage);
// H_BEFORE (serial);
msgout.serial(NbId);
// H_AFTER (serial);
// H_BEFORE (serials);
for (uint i = 0; i < NbId; i++)
msgout.serial( Value );
// H_AFTER(serials);
// H_BEFORE (send);
CUnifiedNetwork::getInstance()->send("FS", msgout);
// H_AFTER (send);
/*
CMessage msgout("VISION");
uint32 Nb = 10;
for (uint j = 0; j < 1000; j++)
{
msgout.clear();
msgout.setType("VISION");
msgout.serial(Nb);
for (uint i = 0; i < Nb; i++)
msgout.serial( Value );
CUnifiedNetwork::getInstance()->send("FS", msgout);
}
*/
TCPUCycle v2 = CTime::getPerformanceTime ();
// H_AFTER (Vision);
// ca prend bcp de cpu un info...
nlinfo("Sent Vision with %d values in %.2fms", NbId, CTime::ticksToSecond (v2-v1)*1000.0f);
}
//
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 cbUpFS(const std::string &serviceName, TServiceId sid, void *arg)
{
nlinfo("F Service connecting");
sendPing();
}
void cbDownFS(const std::string &serviceName, TServiceId sid, void *arg)
{
nlinfo("F Service disconnecting");
}
//
void cbUpService(const std::string &serviceName, TServiceId sid, void *arg)
{
nlinfo("Service %s %d is up", serviceName.c_str(), sid.get());
CMessage msgout("TOTO");
uint32 i = 10;
msgout.serial(i);
CUnifiedNetwork::getInstance()->send(sid, msgout);
}
void cbDownService(const std::string &serviceName, TServiceId sid, void *arg)
{
nlinfo("Service %s %d is down", serviceName.c_str(), sid.get());
}
/*
* Callback array for messages received from a client
*/
TUnifiedCallbackItem CallbackArray[] =
{
{ "PONG", cbPong },
{ "POS", cbPos },
{ "ASK_VISION", cbAskVision }
};
void cbVar (CConfigFile::CVar &var)
{
if (var.Name == "NbId") NbId = var.asInt ();
else nlstop;
}
//
class CGPMService : public IService
{
public:
bool update()
{
static TTime lastPing = CTime::getLocalTime();
TTime ctime = CTime::getLocalTime();
/*
// check ping every 15 seconds
if (ctime - lastPing > 15000)
{
sendPing();
lastPing = ctime;
}
*/
return true;
}
/*
* Initialization
*/
void init()
{
// nlerror ("oups");
/* //nlassert(false);
char *p=0;
p[0]=0;
printf(p);
*/
ConfigFile.setCallback ("NbId", cbVar);
cbVar (ConfigFile.getVar ("NbId"));
// Connect to the ping service
CUnifiedNetwork *instance = CUnifiedNetwork::getInstance();
instance->setServiceUpCallback("PS", cbUpPS, NULL);
instance->setServiceDownCallback("PS", cbDownPS, NULL);
instance->setServiceUpCallback("FS", cbUpFS, NULL);
instance->setServiceDownCallback("FS", cbDownFS, NULL);
instance->setServiceUpCallback("*", cbUpService, NULL);
instance->setServiceDownCallback("*", cbDownService, NULL);
}
};
/*
* Declare a service with the class IService, the names "PS" (short) and "ping_service" (long).
* The port is automatically allocated (0) and the main callback array is CallbackArray.
*/
NLNET_SERVICE_MAIN( CGPMService, "GPMS", "gpm_service", 0, CallbackArray, "", "" )
NLMISC_COMMAND (wait, "", "<time>")
{
if(args.size() != 1) return false;
nlSleep (atoi (args[0].c_str()));
return true;
}