improved packet loss handling

This commit is contained in:
Max-Wilhelm Bruker 2011-03-03 02:09:29 +01:00
parent 657f97680a
commit d6083a85c7
6 changed files with 26 additions and 19 deletions

View file

@ -6,7 +6,7 @@
#include "protocol_items.h" #include "protocol_items.h"
RemoteClient::RemoteClient(QObject *parent) RemoteClient::RemoteClient(QObject *parent)
: AbstractClient(parent), topLevelItem(0) : AbstractClient(parent), timeRunning(0), lastDataReceived(0), topLevelItem(0)
{ {
ProtocolItem::initializeHash(); ProtocolItem::initializeHash();
@ -38,6 +38,7 @@ void RemoteClient::slotSocketError(QAbstractSocket::SocketError /*error*/)
void RemoteClient::slotConnected() void RemoteClient::slotConnected()
{ {
timeRunning = lastDataReceived = 0;
timer->start(); timer->start();
setStatus(StatusAwaitingWelcome); setStatus(StatusAwaitingWelcome);
} }
@ -65,6 +66,7 @@ void RemoteClient::readData()
QByteArray data = socket->readAll(); QByteArray data = socket->readAll();
qDebug() << data; qDebug() << data;
xmlReader->addData(data); xmlReader->addData(data);
lastDataReceived = timeRunning;
while (!xmlReader->atEnd()) { while (!xmlReader->atEnd()) {
xmlReader->readNext(); xmlReader->readNext();
@ -130,17 +132,21 @@ void RemoteClient::disconnectFromServer()
void RemoteClient::ping() void RemoteClient::ping()
{ {
int maxTime = 0; QMutableMapIterator<int, CommandContainer *> i(pendingCommands);
QMapIterator<int, CommandContainer *> i(pendingCommands); while (i.hasNext())
while (i.hasNext()) { if (i.next().value()->tick() > maxTimeout) {
int time = i.next().value()->tick(); CommandContainer *cont = i.value();
if (time > maxTime) i.remove();
maxTime = time; cont->deleteLater();
} }
int maxTime = timeRunning - lastDataReceived;
emit maxPingTime(maxTime, maxTimeout); emit maxPingTime(maxTime, maxTimeout);
if (maxTime >= maxTimeout) { if (maxTime >= maxTimeout) {
emit serverTimeout();
disconnectFromServer(); disconnectFromServer();
} else emit serverTimeout();
} else {
sendCommand(new Command_Ping); sendCommand(new Command_Ping);
++timeRunning;
}
} }

View file

@ -24,6 +24,7 @@ private slots:
void loginResponse(ProtocolResponse *response); void loginResponse(ProtocolResponse *response);
private: private:
static const int maxTimeout = 10; static const int maxTimeout = 10;
int timeRunning, lastDataReceived;
QTimer *timer; QTimer *timer;
QTcpSocket *socket; QTcpSocket *socket;

View file

@ -58,7 +58,6 @@ void Server_Game::pingClockTimeout()
{ {
++secondsElapsed; ++secondsElapsed;
QDateTime now = QDateTime::currentDateTime();
QList<ServerInfo_PlayerPing *> pingList; QList<ServerInfo_PlayerPing *> pingList;
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
bool allPlayersInactive = true; bool allPlayersInactive = true;
@ -66,7 +65,7 @@ void Server_Game::pingClockTimeout()
Server_Player *player = playerIterator.next().value(); Server_Player *player = playerIterator.next().value();
int pingTime; int pingTime;
if (player->getProtocolHandler()) { if (player->getProtocolHandler()) {
pingTime = player->getProtocolHandler()->getLastCommandTime().secsTo(now); pingTime = player->getProtocolHandler()->getLastCommandTime();
allPlayersInactive = false; allPlayersInactive = false;
} else } else
pingTime = -1; pingTime = -1;

View file

@ -14,7 +14,7 @@
#include <QDateTime> #include <QDateTime>
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), lastCommandTime(QDateTime::currentDateTime()) : QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), timeRunning(0), lastDataReceived(0)
{ {
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
} }
@ -58,8 +58,6 @@ void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game)
ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, CommandContainer *cont) ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, CommandContainer *cont)
{ {
lastCommandTime = QDateTime::currentDateTime();
RoomCommand *roomCommand = qobject_cast<RoomCommand *>(command); RoomCommand *roomCommand = qobject_cast<RoomCommand *>(command);
if (roomCommand) { if (roomCommand) {
qDebug() << "received RoomCommand: roomId =" << roomCommand->getRoomId(); qDebug() << "received RoomCommand: roomId =" << roomCommand->getRoomId();
@ -159,6 +157,8 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm
void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont) void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont)
{ {
lastDataReceived = timeRunning;
const QList<Command *> &cmdList = cont->getCommandList(); const QList<Command *> &cmdList = cont->getCommandList();
ResponseCode finalResponseCode = RespOk; ResponseCode finalResponseCode = RespOk;
for (int i = 0; i < cmdList.size(); ++i) { for (int i = 0; i < cmdList.size(); ++i) {
@ -219,8 +219,9 @@ void Server_ProtocolHandler::pingClockTimeout()
messageCountOverTime.removeLast(); messageCountOverTime.removeLast();
} }
if (lastCommandTime.secsTo(QDateTime::currentDateTime()) > server->getMaxPlayerInactivityTime()) if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime())
deleteLater(); deleteLater();
++timeRunning;
} }
void Server_ProtocolHandler::enqueueProtocolItem(ProtocolItem *item) void Server_ProtocolHandler::enqueueProtocolItem(ProtocolItem *item)

View file

@ -31,7 +31,7 @@ protected:
private: private:
QList<ProtocolItem *> itemQueue; QList<ProtocolItem *> itemQueue;
QList<int> messageSizeOverTime, messageCountOverTime; QList<int> messageSizeOverTime, messageCountOverTime;
QDateTime lastCommandTime; int timeRunning, lastDataReceived;
QTimer *pingClock; QTimer *pingClock;
virtual DeckList *getDeckFromDatabase(int deckId) = 0; virtual DeckList *getDeckFromDatabase(int deckId) = 0;
@ -101,8 +101,8 @@ public:
void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; } void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; }
const QMap<QString, ServerInfo_User *> &getBuddyList() const { return buddyList; } const QMap<QString, ServerInfo_User *> &getBuddyList() const { return buddyList; }
const QMap<QString, ServerInfo_User *> &getIgnoreList() const { return ignoreList; } const QMap<QString, ServerInfo_User *> &getIgnoreList() const { return ignoreList; }
const QDateTime &getLastCommandTime() const { return lastCommandTime; }
int getLastCommandTime() const { return timeRunning - lastDataReceived; }
void processCommandContainer(CommandContainer *cont); void processCommandContainer(CommandContainer *cont);
virtual void sendProtocolItem(ProtocolItem *item, bool deleteItem = true) = 0; virtual void sendProtocolItem(ProtocolItem *item, bool deleteItem = true) = 0;
void enqueueProtocolItem(ProtocolItem *item); void enqueueProtocolItem(ProtocolItem *item);

View file

@ -432,7 +432,7 @@ ResponseCode ServerSocketInterface::cmdUpdateServerMessage(Command_UpdateServerM
return RespOk; return RespOk;
} }
ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer *cont) ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer * /*cont*/)
{ {
QString userName = cmd->getUserName(); QString userName = cmd->getUserName();
if (!server->getUsers().contains(userName)) if (!server->getUsers().contains(userName))