added simple timer system to CNShardServer

This commit is contained in:
CPunch 2020-08-24 16:11:40 -05:00
parent afbf309c7e
commit 16bca39dae
4 changed files with 52 additions and 23 deletions

View File

@ -268,12 +268,8 @@ void CNServer::init() {
} }
} }
CNServer::CNServer() { CNServer::CNServer() {};
lastTimer = getTime(); CNServer::CNServer(uint16_t p): port(p) {}
};
CNServer::CNServer(uint16_t p): port(p) {
lastTimer = getTime();
}
void CNServer::start() { void CNServer::start() {
std::cout << "Starting server at *:" << port << std::endl; std::cout << "Starting server at *:" << port << std::endl;
@ -326,10 +322,7 @@ void CNServer::start() {
} }
} }
if (getTime() - lastTimer > 2000) { // every 2 seconds call the onTimer method onStep();
onTimer();
lastTimer = getTime();
}
#ifdef _WIN32 #ifdef _WIN32
Sleep(0); Sleep(0);
@ -383,4 +376,4 @@ void CNServer::printPacket(CNPacketData *data, int type) {
void CNServer::newConnection(CNSocket* cns) {} // stubbed void CNServer::newConnection(CNSocket* cns) {} // stubbed
void CNServer::killConnection(CNSocket* cns) {} // stubbed void CNServer::killConnection(CNSocket* cns) {} // stubbed
void CNServer::onTimer() {} // stubbed void CNServer::onStep() {} // stubbed

View File

@ -132,6 +132,20 @@ public:
bool isAlive(); bool isAlive();
}; };
class CNServer;
typedef void (*TimerHandler)(CNServer* serv, uint64_t time);
// timer struct
struct TimerEvent {
TimerHandler handlr;
uint64_t delta; // time to be added to the current time on reset
uint64_t scheduledEvent; // time to call handlr()
TimerEvent(TimerHandler h, uint64_t d): handlr(h), delta(d) {
scheduledEvent = 0;
}
};
// in charge of accepting new connections and making sure each connection is kept alive // in charge of accepting new connections and making sure each connection is kept alive
class CNServer { class CNServer {
protected: protected:
@ -145,7 +159,6 @@ protected:
void init(); void init();
bool active = true; bool active = true;
uint64_t lastTimer;
public: public:
PacketHandler pHandler; PacketHandler pHandler;
@ -158,5 +171,5 @@ public:
static void printPacket(CNPacketData *data, int type); static void printPacket(CNPacketData *data, int type);
virtual void newConnection(CNSocket* cns); virtual void newConnection(CNSocket* cns);
virtual void killConnection(CNSocket* cns); virtual void killConnection(CNSocket* cns);
virtual void onTimer(); // called every 2 seconds virtual void onStep(); // called every 2 seconds
}; };

View File

@ -10,10 +10,12 @@
#include <cstdlib> #include <cstdlib>
std::map<uint32_t, PacketHandler> CNShardServer::ShardPackets; std::map<uint32_t, PacketHandler> CNShardServer::ShardPackets;
std::list<TimerEvent> CNShardServer::Timers;
CNShardServer::CNShardServer(uint16_t p) { CNShardServer::CNShardServer(uint16_t p) {
port = p; port = p;
pHandler = &CNShardServer::handlePacket; pHandler = &CNShardServer::handlePacket;
REGISTER_SHARD_TIMER(keepAliveTimer, 2000);
init(); init();
} }
@ -26,6 +28,22 @@ void CNShardServer::handlePacket(CNSocket* sock, CNPacketData* data) {
std::cerr << "OpenFusion: SHARD UNIMPLM ERR. PacketType: " << Defines::p2str(CL2FE, data->type) << " (" << data->type << ")" << std::endl; std::cerr << "OpenFusion: SHARD UNIMPLM ERR. PacketType: " << Defines::p2str(CL2FE, data->type) << " (" << data->type << ")" << std::endl;
} }
void CNShardServer::keepAliveTimer(CNServer* serv, uint64_t currTime) {
std::cout << "keep alive called! " << currTime << std::endl;
auto cachedPlayers = PlayerManager::players;
for (auto pair : cachedPlayers) {
if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > 4000) { // if the client hadn't responded in 4 seconds, its a dead connection so throw it out
pair.first->kill();
continue;
}
// passed the heartbeat, send another
INITSTRUCT(sP_FE2CL_REQ_LIVE_CHECK, data);
pair.first->sendPacket((void*)&data, P_FE2CL_REQ_LIVE_CHECK, sizeof(sP_FE2CL_REQ_LIVE_CHECK));
}
}
void CNShardServer::newConnection(CNSocket* cns) { void CNShardServer::newConnection(CNSocket* cns) {
cns->setActiveKey(SOCKETKEY_E); // by default they accept keys encrypted with the default key cns->setActiveKey(SOCKETKEY_E); // by default they accept keys encrypted with the default key
} }
@ -38,19 +56,20 @@ void CNShardServer::killConnection(CNSocket* cns) {
CNSharedData::erasePlayer(cachedPlr.SerialKey); CNSharedData::erasePlayer(cachedPlr.SerialKey);
} }
void CNShardServer::onTimer() { void CNShardServer::onStep() {
uint64_t currTime = getTime(); uint64_t currTime = getTime();
auto cachedPlayers = PlayerManager::players; for (TimerEvent& event : Timers) {
if (event.scheduledEvent == 0) {
for (auto pair : cachedPlayers) { // event hasn't been queued yet, go ahead and do that
if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > 4000) { // if the client hadn't responded in 4 seconds, its a dead connection so throw it out event.scheduledEvent = currTime + event.delta;
pair.first->kill();
continue; continue;
} }
// passed the heartbeat, send another if (event.scheduledEvent < currTime) {
INITSTRUCT(sP_FE2CL_REQ_LIVE_CHECK, data); // timer needs to be called
pair.first->sendPacket((void*)&data, P_FE2CL_REQ_LIVE_CHECK, sizeof(sP_FE2CL_REQ_LIVE_CHECK)); event.handlr(this, currTime);
event.scheduledEvent = currTime + event.delta;
}
} }
} }

View File

@ -6,17 +6,21 @@
#include <map> #include <map>
#define REGISTER_SHARD_PACKET(pactype, handlr) CNShardServer::ShardPackets[pactype] = handlr; #define REGISTER_SHARD_PACKET(pactype, handlr) CNShardServer::ShardPackets[pactype] = handlr;
#define REGISTER_SHARD_TIMER(handlr, delta) CNShardServer::Timers.push_back(TimerEvent(handlr, delta));
class CNShardServer : public CNServer { class CNShardServer : public CNServer {
private: private:
static void handlePacket(CNSocket* sock, CNPacketData* data); static void handlePacket(CNSocket* sock, CNPacketData* data);
static void keepAliveTimer(CNServer*, uint64_t);
public: public:
static std::map<uint32_t, PacketHandler> ShardPackets; static std::map<uint32_t, PacketHandler> ShardPackets;
static std::list<TimerEvent> Timers;
CNShardServer(uint16_t p); CNShardServer(uint16_t p);
void newConnection(CNSocket* cns); void newConnection(CNSocket* cns);
void killConnection(CNSocket* cns); void killConnection(CNSocket* cns);
void onTimer(); void onStep();
}; };