mirror of
https://github.com/glest/glest-source.git
synced 2025-08-20 07:01:21 +02:00
- fixed server side detection of dropped socket connection when socket is not reporting a disconnect (we periodically do lag checks)
This commit is contained in:
@@ -56,6 +56,7 @@ ServerInterface::ServerInterface(bool publishEnabled) :GameNetworkInterface() {
|
|||||||
needToRepublishToMasterserver = false;
|
needToRepublishToMasterserver = false;
|
||||||
ftpServer = NULL;
|
ftpServer = NULL;
|
||||||
inBroadcastMessage = false;
|
inBroadcastMessage = false;
|
||||||
|
lastGlobalLagCheckTime = 0;
|
||||||
|
|
||||||
maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed", intToStr(maxFrameCountLagAllowed).c_str());
|
maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed", intToStr(maxFrameCountLagAllowed).c_str());
|
||||||
maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver", intToStr(maxFrameCountLagAllowedEver).c_str());
|
maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver", intToStr(maxFrameCountLagAllowedEver).c_str());
|
||||||
@@ -415,6 +416,17 @@ std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot *connectionS
|
|||||||
|
|
||||||
std::pair<bool,bool> clientLagExceededOrWarned = std::make_pair(false, false);
|
std::pair<bool,bool> clientLagExceededOrWarned = std::make_pair(false, false);
|
||||||
static bool alreadyInLagCheck = false;
|
static bool alreadyInLagCheck = false;
|
||||||
|
|
||||||
|
// {
|
||||||
|
// if(connectionSlot != NULL && connectionSlot->isConnected() == true) {
|
||||||
|
// double clientLag = this->getCurrentFrameCount() - connectionSlot->getCurrentFrameCount();
|
||||||
|
// double clientLagCount = (gameSettings.getNetworkFramePeriod() > 0 ? (clientLag / gameSettings.getNetworkFramePeriod()) : 0);
|
||||||
|
// double clientLagTime = difftime(time(NULL),connectionSlot->getLastReceiveCommandListTime());
|
||||||
|
//
|
||||||
|
// printf("\n\nmaxClientLagTimeAllowedEver [%f] - [%f] alreadyInLagCheck = %d\n\n",maxClientLagTimeAllowedEver,clientLagTime,alreadyInLagCheck);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if(alreadyInLagCheck == true) {
|
if(alreadyInLagCheck == true) {
|
||||||
return clientLagExceededOrWarned;
|
return clientLagExceededOrWarned;
|
||||||
}
|
}
|
||||||
@@ -455,11 +467,12 @@ std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot *connectionS
|
|||||||
*/
|
*/
|
||||||
// END test
|
// END test
|
||||||
|
|
||||||
|
|
||||||
// New lag check
|
// New lag check
|
||||||
if((maxFrameCountLagAllowed > 0 && clientLagCount > maxFrameCountLagAllowed) ||
|
if((maxFrameCountLagAllowed > 0 && clientLagCount > maxFrameCountLagAllowed) ||
|
||||||
(maxClientLagTimeAllowed > 0 && clientLagTime > maxClientLagTimeAllowed) ||
|
(maxClientLagTimeAllowed > 0 && clientLagTime > maxClientLagTimeAllowed) ||
|
||||||
((maxFrameCountLagAllowedEver > 0 && clientLagCount > maxFrameCountLagAllowedEver) ||
|
(maxFrameCountLagAllowedEver > 0 && clientLagCount > maxFrameCountLagAllowedEver) ||
|
||||||
maxClientLagTimeAllowedEver > 0 && clientLagTime > maxClientLagTimeAllowedEver)) {
|
( maxClientLagTimeAllowedEver > 0 && clientLagTime > maxClientLagTimeAllowedEver)) {
|
||||||
clientLagExceededOrWarned.first = true;
|
clientLagExceededOrWarned.first = true;
|
||||||
|
|
||||||
Lang &lang= Lang::getInstance();
|
Lang &lang= Lang::getInstance();
|
||||||
@@ -472,8 +485,8 @@ std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot *connectionS
|
|||||||
msgTemplate = lang.get("ClientLagDropping",languageList[i]);
|
msgTemplate = lang.get("ClientLagDropping",languageList[i]);
|
||||||
}
|
}
|
||||||
if(gameSettings.getNetworkPauseGameForLaggedClients() == true &&
|
if(gameSettings.getNetworkPauseGameForLaggedClients() == true &&
|
||||||
(maxFrameCountLagAllowedEver <= 0 || clientLagCount <= maxFrameCountLagAllowedEver ||
|
((maxFrameCountLagAllowedEver <= 0 || clientLagCount <= maxFrameCountLagAllowedEver) &&
|
||||||
maxClientLagTimeAllowedEver <= 0 || clientLagTime <= maxClientLagTimeAllowedEver)) {
|
(maxClientLagTimeAllowedEver <= 0 || clientLagTime <= maxClientLagTimeAllowedEver))) {
|
||||||
msgTemplate = "PAUSING GAME TEMPORARILY for %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], waiting for client to catch up...";
|
msgTemplate = "PAUSING GAME TEMPORARILY for %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], waiting for client to catch up...";
|
||||||
if(lang.hasString("ClientLagPausing") == true) {
|
if(lang.hasString("ClientLagPausing") == true) {
|
||||||
msgTemplate = lang.get("ClientLagPausing",languageList[i]);
|
msgTemplate = lang.get("ClientLagPausing",languageList[i]);
|
||||||
@@ -672,6 +685,7 @@ void ServerInterface::checForLaggingClients(std::map<int,bool> &mapSlotSignalled
|
|||||||
std::map<int,ConnectionSlotEvent> &eventList,
|
std::map<int,ConnectionSlotEvent> &eventList,
|
||||||
std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,
|
std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,
|
||||||
std::vector <string> &errorMsgList) {
|
std::vector <string> &errorMsgList) {
|
||||||
|
bool lastGlobalLagCheckTimeUpdate = false;
|
||||||
time_t waitForClientsElapsed = time(NULL);
|
time_t waitForClientsElapsed = time(NULL);
|
||||||
time_t waitForThreadElapsed = time(NULL);
|
time_t waitForThreadElapsed = time(NULL);
|
||||||
std::map<int,bool> slotsCompleted;
|
std::map<int,bool> slotsCompleted;
|
||||||
@@ -752,9 +766,45 @@ void ServerInterface::checForLaggingClients(std::map<int,bool> &mapSlotSignalled
|
|||||||
errorMsgList.push_back(ex.what());
|
errorMsgList.push_back(ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(connectionSlot != NULL && connectionSlot->isConnected() == true) {
|
||||||
|
try {
|
||||||
|
if(gameHasBeenInitiated == true &&
|
||||||
|
difftime(time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
|
||||||
|
|
||||||
|
printf("\n\n\n^^^^^^^^^^^^^^ PART A\n\n\n");
|
||||||
|
|
||||||
|
// New lag check
|
||||||
|
std::pair<bool,bool> clientLagExceededOrWarned = std::make_pair(false,false);
|
||||||
|
if( gameHasBeenInitiated == true && connectionSlot != NULL &&
|
||||||
|
connectionSlot->isConnected() == true) {
|
||||||
|
|
||||||
|
printf("\n\n\n^^^^^^^^^^^^^^ PART B\n\n\n");
|
||||||
|
|
||||||
|
lastGlobalLagCheckTimeUpdate = true;
|
||||||
|
clientLagExceededOrWarned = clientLagCheck(connectionSlot,slotsWarnedList[i]);
|
||||||
|
|
||||||
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, gameSettings.getNetworkPauseGameForLaggedClients() = %d\n",__FILE__,__FUNCTION__,__LINE__,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second,gameSettings.getNetworkPauseGameForLaggedClients());
|
||||||
|
|
||||||
|
if(clientLagExceededOrWarned.first == true) {
|
||||||
|
slotsWarnedList[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch(const exception &ex) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
|
errorMsgList.push_back(ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lastGlobalLagCheckTimeUpdate == true) {
|
||||||
|
lastGlobalLagCheckTime = time(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ServerInterface::executeNetworkCommandsFromClients() {
|
void ServerInterface::executeNetworkCommandsFromClients() {
|
||||||
if(gameHasBeenInitiated == true) {
|
if(gameHasBeenInitiated == true) {
|
||||||
@@ -825,26 +875,36 @@ void ServerInterface::update() {
|
|||||||
Chrono chrono;
|
Chrono chrono;
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||||
|
|
||||||
|
//printf("\nServerInterface::update -- A\n");
|
||||||
|
|
||||||
std::vector <string> errorMsgList;
|
std::vector <string> errorMsgList;
|
||||||
try {
|
try {
|
||||||
// The first thing we will do is check all clients to ensure they have
|
// The first thing we will do is check all clients to ensure they have
|
||||||
// properly identified themselves within the alloted time period
|
// properly identified themselves within the alloted time period
|
||||||
validateConnectedClients();
|
validateConnectedClients();
|
||||||
|
|
||||||
|
//printf("\nServerInterface::update -- B\n");
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
|
|
||||||
processTextMessageQueue();
|
processTextMessageQueue();
|
||||||
processBroadCastMessageQueue();
|
processBroadCastMessageQueue();
|
||||||
|
|
||||||
|
//printf("\nServerInterface::update -- C\n");
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
|
|
||||||
std::map<PLATFORM_SOCKET,bool> socketTriggeredList;
|
std::map<PLATFORM_SOCKET,bool> socketTriggeredList;
|
||||||
//update all slots
|
//update all slots
|
||||||
updateSocketTriggeredList(socketTriggeredList);
|
updateSocketTriggeredList(socketTriggeredList);
|
||||||
|
|
||||||
|
//printf("\nServerInterface::update -- D\n");
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
|
|
||||||
if(gameHasBeenInitiated == false || socketTriggeredList.size() > 0) {
|
if(gameHasBeenInitiated == false || socketTriggeredList.size() > 0) {
|
||||||
|
//printf("\nServerInterface::update -- E\n");
|
||||||
|
|
||||||
std::map<int,ConnectionSlotEvent> eventList;
|
std::map<int,ConnectionSlotEvent> eventList;
|
||||||
bool hasData = Socket::hasDataToRead(socketTriggeredList);
|
bool hasData = Socket::hasDataToRead(socketTriggeredList);
|
||||||
|
|
||||||
@@ -885,11 +945,33 @@ void ServerInterface::update() {
|
|||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
}
|
}
|
||||||
|
else if(gameHasBeenInitiated == true &&
|
||||||
|
difftime(time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
|
||||||
|
//printf("\nServerInterface::update -- E1\n");
|
||||||
|
|
||||||
|
//std::map<int,ConnectionSlotEvent> eventList;
|
||||||
|
std::map<int,bool> mapSlotSignalledList;
|
||||||
|
|
||||||
|
checForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
|
||||||
|
}
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
}
|
}
|
||||||
|
else if(gameHasBeenInitiated == true &&
|
||||||
|
difftime(time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_GRACE_PERIOD) {
|
||||||
|
//printf("\nServerInterface::update -- F\n");
|
||||||
|
|
||||||
|
std::map<int,ConnectionSlotEvent> eventList;
|
||||||
|
std::map<int,bool> mapSlotSignalledList;
|
||||||
|
|
||||||
|
checForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("\nServerInterface::update -- G\n");
|
||||||
}
|
}
|
||||||
catch(const exception &ex) {
|
catch(const exception &ex) {
|
||||||
|
//printf("\nServerInterface::update -- H\n");
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
errorMsgList.push_back(ex.what());
|
errorMsgList.push_back(ex.what());
|
||||||
|
@@ -59,6 +59,8 @@ private:
|
|||||||
|
|
||||||
time_t gameStartTime;
|
time_t gameStartTime;
|
||||||
|
|
||||||
|
time_t lastGlobalLagCheckTime;
|
||||||
|
|
||||||
SimpleTaskThread *publishToMasterserverThread;
|
SimpleTaskThread *publishToMasterserverThread;
|
||||||
Mutex masterServerThreadAccessor;
|
Mutex masterServerThreadAccessor;
|
||||||
time_t lastMasterserverHeartbeatTime;
|
time_t lastMasterserverHeartbeatTime;
|
||||||
|
Reference in New Issue
Block a user