#include #include "ProtoClientConnection.h" // qt #include #include #include ProtoServer::ProtoServer(const QJsonDocument& config, QObject* parent) : QObject(parent) , _server(new QTcpServer(this)) , _log(Logger::getInstance("PROTOSERVER")) , _timeout(5000) , _config(config) { } ProtoServer::~ProtoServer() { stopServer(); delete _server; } void ProtoServer::initServer() { connect(_server, &QTcpServer::newConnection, this, &ProtoServer::newConnection); // apply config handleSettingsUpdate(settings::PROTOSERVER, _config); } void ProtoServer::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) { if(type == settings::PROTOSERVER) { const QJsonObject& obj = config.object(); quint16 port = obj["port"].toInt(19445); // port check if(_server->serverPort() != port) { stopServer(); _port = port; } // new timeout just for new connections _timeout = obj["timeout"].toInt(5000); // enable check obj["enable"].toBool(true) ? startServer() : stopServer(); } } void ProtoServer::newConnection() { while(_server->hasPendingConnections()) { if(QTcpSocket * socket = _server->nextPendingConnection()) { Debug(_log, "New connection from %s", QSTRING_CSTR(socket->peerAddress().toString())); ProtoClientConnection * client = new ProtoClientConnection(socket, _timeout, this); // internal connect(client, &ProtoClientConnection::clientDisconnected, this, &ProtoServer::clientDisconnected); _openConnections.append(client); } } } void ProtoServer::clientDisconnected() { ProtoClientConnection* client = qobject_cast(sender()); client->deleteLater(); _openConnections.removeAll(client); } void ProtoServer::startServer() { if(!_server->isListening()) { if(!_server->listen(QHostAddress::Any, _port)) { Error(_log,"Failed to bind port %d", _port); } else { Info(_log,"Started on port %d", _port); } } } void ProtoServer::stopServer() { if(_server->isListening()) { // close client connections for(const auto& client : _openConnections) { client->forceClose(); } _server->close(); Info(_log, "Stopped"); } }