Implementation of websockets in servatrice and test js client

This commit is contained in:
Fabio Bas 2015-12-24 17:40:49 +01:00
parent e81a6d497b
commit 5b21dc8cde
42 changed files with 39592 additions and 287 deletions

View file

@ -37,8 +37,8 @@
#include <QThread>
#include <QDebug>
Server::Server(bool _threaded, QObject *parent)
: QObject(parent), threaded(_threaded), nextLocalGameId(0)
Server::Server(QObject *parent)
: QObject(parent), nextLocalGameId(0)
{
qRegisterMetaType<ServerInfo_Ban>("ServerInfo_Ban");
qRegisterMetaType<ServerInfo_Game>("ServerInfo_Game");
@ -60,32 +60,26 @@ Server::~Server()
void Server::prepareDestroy()
{
// dirty :(
if (threaded) {
clientsLock.lockForRead();
for (int i = 0; i < clients.size(); ++i)
QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection);
clientsLock.unlock();
bool done = false;
class SleeperThread : public QThread
{
public:
static void msleep(unsigned long msecs) { QThread::usleep(msecs); }
};
do {
SleeperThread::msleep(10);
clientsLock.lockForRead();
for (int i = 0; i < clients.size(); ++i)
QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection);
if (clients.isEmpty())
done = true;
clientsLock.unlock();
bool done = false;
class SleeperThread : public QThread
{
public:
static void msleep(unsigned long msecs) { QThread::usleep(msecs); }
};
do {
SleeperThread::msleep(10);
clientsLock.lockForRead();
if (clients.isEmpty())
done = true;
clientsLock.unlock();
} while (!done);
} else {
// no locking is needed in unthreaded mode
while (!clients.isEmpty())
clients.first()->prepareDestroy();
}
} while (!done);
roomsLock.lockForWrite();
QMapIterator<int, Server_Room *> roomIterator(rooms);
@ -106,7 +100,7 @@ Server_DatabaseInterface *Server::getDatabaseInterface() const
return databaseInterfaces.value(QThread::currentThread());
}
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft, QString &clientid, QString &clientVersion)
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft, QString &clientid, QString &clientVersion, QString & /* connectionType */)
{
if (name.size() > 35)
name = name.left(35);
@ -162,7 +156,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
users.insert(name, session);
qDebug() << "Server::loginUser:" << session << "name=" << name;
data.set_session_id(databaseInterface->startSession(name, session->getAddress(), clientid));
data.set_session_id(databaseInterface->startSession(name, session->getAddress(), clientid, session->getConnectionType()));
databaseInterface->unlockSessionTables();
usersBySessionId.insert(data.session_id(), session);

View file

@ -44,10 +44,9 @@ private slots:
void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
public:
mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock
Server(bool _threaded, QObject *parent = 0);
Server(QObject *parent = 0);
~Server();
void setThreaded(bool _threaded) { threaded = _threaded; }
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft, QString &clientid, QString &clientVersion);
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft, QString &clientid, QString &clientVersion, QString &connectionType);
const QMap<int, Server_Room *> &getRooms() { return rooms; }
@ -73,8 +72,6 @@ public:
virtual int getCommandCountingInterval() const { return 0; }
virtual int getMaxCommandCountPerInterval() const { return 0; }
virtual bool getThreaded() const { return false; }
Server_DatabaseInterface *getDatabaseInterface() const;
int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; }
@ -93,7 +90,6 @@ public:
void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
QList<PlayerReference> getPersistentPlayerReferences(const QString &userName) const;
private:
bool threaded;
QMultiMap<QString, PlayerReference> persistentPlayers;
mutable QReadWriteLock persistentPlayersLock;
int nextLocalGameId;

View file

@ -22,14 +22,14 @@ public:
virtual void storeGameInformation(const QString & /* roomName */, const QStringList & /* roomGameTypes */, const ServerInfo_Game & /* gameInfo */, const QSet<QString> & /* allPlayersEver */, const QSet<QString> & /* allSpectatorsEver */, const QList<GameReplay *> & /* replayList */) { }
virtual DeckList *getDeckFromDatabase(int /* deckId */, int /* userId */) { return 0; }
virtual qint64 startSession(const QString & /* userName */, const QString & /* address */, const QString & /* clientId */) { return 0; }
virtual qint64 startSession(const QString & /* userName */, const QString & /* address */, const QString & /* clientId */, const QString & /* connectionType */) { return 0; }
virtual bool usernameIsValid(const QString & /*userName */, QString & /* error */) { return true; };
public slots:
virtual void endSession(qint64 /* sessionId */ ) { }
public:
virtual int getNextGameId() = 0;
virtual int getNextReplayId() = 0;
virtual int getActiveUserCount() = 0;
virtual int getActiveUserCount(QString connectionType = QString()) = 0;
virtual void clearSessionTables() { }
virtual void lockSessionTables() { }

View file

@ -414,7 +414,8 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
QString reasonStr;
int banSecondsLeft = 0;
AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft, clientId, clientVersion);
QString connectionType = getConnectionType();
AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft, clientId, clientVersion, connectionType);
switch (res) {
case UserIsBanned: {
Response_Login *re = new Response_Login;

View file

@ -92,6 +92,7 @@ public:
bool getAcceptsUserListChanges() const { return acceptsUserListChanges; }
bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; }
virtual QString getAddress() const = 0;
virtual QString getConnectionType() const = 0;
Server_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; }
int getLastCommandTime() const { return timeRunning - lastDataReceived; }