Skip to content
Snippets Groups Projects
websocketserver.cpp 11.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • akiraohgaki's avatar
    akiraohgaki committed
    #include "websocketserver.h"
    
    #include <QHostAddress>
    #include <QWebSocketServer>
    
    akiraohgaki's avatar
    akiraohgaki committed
    #include <QWebSocket>
    
    #include "qtlib_json.h"
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    #include "handlers/confighandler.h"
    #include "handlers/systemhandler.h"
    #include "handlers/ocshandler.h"
    #include "handlers/itemhandler.h"
    
    WebSocketServer::WebSocketServer(ConfigHandler *configHandler, const QString &serverName, quint16 serverPort, QObject *parent)
        : QObject(parent), configHandler_(configHandler), serverName_(serverName), serverPort_(serverPort)
    
    akiraohgaki's avatar
    akiraohgaki committed
        wsServer_ = new QWebSocketServer(serverName_, QWebSocketServer::NonSecureMode, this);
        connect(wsServer_, &QWebSocketServer::newConnection, this, &WebSocketServer::wsNewConnection);
        connect(wsServer_, &QWebSocketServer::closed, this, &WebSocketServer::stopped);
    
    akiraohgaki's avatar
    akiraohgaki committed
    
        configHandler_->setParent(this);
        systemHandler_ = new SystemHandler(this);
        ocsHandler_ = new OcsHandler(configHandler_, this);
        itemHandler_ = new ItemHandler(configHandler_, this);
    
    akiraohgaki's avatar
    akiraohgaki committed
        connect(itemHandler_, &ItemHandler::metadataSetChanged, this, &WebSocketServer::itemMetadataSetChanged);
        connect(itemHandler_, &ItemHandler::downloadStarted, this, &WebSocketServer::itemDownloadStarted);
        connect(itemHandler_, &ItemHandler::downloadFinished, this, &WebSocketServer::itemDownloadFinished);
        connect(itemHandler_, &ItemHandler::downloadProgress, this, &WebSocketServer::itemDownloadProgress);
        connect(itemHandler_, &ItemHandler::installStarted, this, &WebSocketServer::itemInstallStarted);
        connect(itemHandler_, &ItemHandler::installFinished, this, &WebSocketServer::itemInstallFinished);
        connect(itemHandler_, &ItemHandler::uninstallStarted, this, &WebSocketServer::itemUninstallStarted);
        connect(itemHandler_, &ItemHandler::uninstallFinished, this, &WebSocketServer::itemUninstallFinished);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    WebSocketServer::~WebSocketServer()
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        stop();
    
    akiraohgaki's avatar
    akiraohgaki committed
        wsServer_->deleteLater();
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    bool WebSocketServer::start()
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (wsServer_->listen(QHostAddress::Any, serverPort_)) {
    
    akiraohgaki's avatar
    akiraohgaki committed
            emit started();
            return true;
        }
        return false;
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::stop()
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        wsServer_->close();
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    bool WebSocketServer::isError()
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (wsServer_->error() != QWebSocketProtocol::CloseCodeNormal) {
    
    akiraohgaki's avatar
    akiraohgaki committed
            return true;
        }
        return false;
    }
    
    QString WebSocketServer::errorString()
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        return wsServer_->errorString();
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    QUrl WebSocketServer::serverUrl()
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        return wsServer_->serverUrl();
    }
    
    void WebSocketServer::wsNewConnection()
    {
        QWebSocket *wsClient = wsServer_->nextPendingConnection();
        connect(wsClient, &QWebSocket::disconnected, this, &WebSocketServer::wsDisconnected);
    
    akiraohgaki's avatar
    akiraohgaki committed
        connect(wsClient, &QWebSocket::textMessageReceived, this, &WebSocketServer::wsTextMessageReceived);
        connect(wsClient, &QWebSocket::binaryMessageReceived, this, &WebSocketServer::wsBinaryMessageReceived);
    
    akiraohgaki's avatar
    akiraohgaki committed
        wsClients_ << wsClient;
    }
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    void WebSocketServer::wsDisconnected()
    
    akiraohgaki's avatar
    akiraohgaki committed
    {
        QWebSocket *wsClient = qobject_cast<QWebSocket *>(sender());
        if (wsClient) {
    
    akiraohgaki's avatar
    akiraohgaki committed
            wsClients_.removeAll(wsClient);
            wsClient->deleteLater();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    }
    
    void WebSocketServer::wsTextMessageReceived(const QString &message)
    {
        QWebSocket *wsClient = qobject_cast<QWebSocket *>(sender());
        if (wsClient) {
    
            qtlib::Json json(message.toUtf8());
    
    akiraohgaki's avatar
    akiraohgaki committed
            if (json.isObject()) {
                QJsonObject object = json.toObject();
                receiveMessage(object["id"].toString(), object["func"].toString(), object["data"].toArray());
    
    akiraohgaki's avatar
    akiraohgaki committed
    void WebSocketServer::wsBinaryMessageReceived(const QByteArray &message)
    
    akiraohgaki's avatar
    akiraohgaki committed
    {
        QWebSocket *wsClient = qobject_cast<QWebSocket *>(sender());
        if (wsClient) {
    
    akiraohgaki's avatar
    akiraohgaki committed
            qtlib::Json json(message);
    
    akiraohgaki's avatar
    akiraohgaki committed
            if (json.isObject()) {
                QJsonObject object = json.toObject();
                receiveMessage(object["id"].toString(), object["func"].toString(), object["data"].toArray());
    
    akiraohgaki's avatar
    akiraohgaki committed
            }
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    void WebSocketServer::itemMetadataSetChanged()
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        sendMessage("", "ItemHandler::metadataSetChanged", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::itemDownloadStarted(QJsonObject result)
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        data[0] = result;
        sendMessage("", "ItemHandler::downloadStarted", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::itemDownloadFinished(QJsonObject result)
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        data[0] = result;
        sendMessage("", "ItemHandler::downloadFinished", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::itemDownloadProgress(QString id, qint64 bytesReceived, qint64 bytesTotal)
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        data[0] = id;
        data[1] = bytesReceived;
        data[2] = bytesTotal;
        sendMessage("", "ItemHandler::downloadProgress", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::itemInstallStarted(QJsonObject result)
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        data[0] = result;
        sendMessage("", "ItemHandler::installStarted", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::itemInstallFinished(QJsonObject result)
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        data[0] = result;
        sendMessage("", "ItemHandler::installFinished", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::itemUninstallStarted(QJsonObject result)
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        data[0] = result;
        sendMessage("", "ItemHandler::uninstallStarted", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    void WebSocketServer::itemUninstallFinished(QJsonObject result)
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray data;
        data[0] = result;
        sendMessage("", "ItemHandler::uninstallFinished", data);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    void WebSocketServer::receiveMessage(const QString &id, const QString &func, const QJsonArray &data)
    
    akiraohgaki's avatar
    akiraohgaki committed
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        /* message object format
    
    akiraohgaki's avatar
    akiraohgaki committed
        {
            "id": "example",
    
    akiraohgaki's avatar
    akiraohgaki committed
            "func": "functionName",
    
    akiraohgaki's avatar
    akiraohgaki committed
            "data": ["value", 2, true]
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
        */
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonArray resultData;
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        // WebSocketServer
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (func == "WebSocketServer::stop") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            stop();
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "WebSocketServer::isError") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = isError();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "WebSocketServer::errorString") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = errorString();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "WebSocketServer::serverUrl") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = serverUrl().toString();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        // ConfigHandler
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::getAppConfigApplication") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->getAppConfigApplication();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::getAppConfigInstallTypes") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->getAppConfigInstallTypes();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::getUsrConfigApplication") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->getUsrConfigApplication();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigApplication") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigApplication(data[0].toObject());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::getUsrConfigProviders") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->getUsrConfigProviders();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigProviders") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigProviders(data[0].toObject());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::getUsrConfigCategories") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->getUsrConfigCategories();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigCategories") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigCategories(data[0].toObject());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::getUsrConfigInstalledItems") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->getUsrConfigInstalledItems();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigInstalledItems") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigInstalledItems(data[0].toObject());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigProvidersProvider") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigProvidersProvider(data[0].toString(), data[1].toObject());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::removeUsrConfigProvidersProvider") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->removeUsrConfigProvidersProvider(data[0].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigCategoriesProvider") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigCategoriesProvider(data[0].toString(), data[1].toObject());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::removeUsrConfigCategoriesProvider") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->removeUsrConfigCategoriesProvider(data[0].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigCategoriesInstallType") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigCategoriesInstallType(data[0].toString(), data[1].toString(), data[2].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::setUsrConfigInstalledItemsItem") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->setUsrConfigInstalledItemsItem(data[0].toString(), data[1].toObject());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ConfigHandler::removeUsrConfigInstalledItemsItem") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = configHandler_->removeUsrConfigInstalledItemsItem(data[0].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        // SystemHandler
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "SystemHandler::isUnix") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = systemHandler_->isUnix();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "SystemHandler::desktopEnvironment") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = systemHandler_->desktopEnvironment();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "SystemHandler::isApplicableType") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = systemHandler_->isApplicableType(data[0].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "SystemHandler::applyFile") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = false;
    
    akiraohgaki's avatar
    akiraohgaki committed
    #ifdef QTLIB_UNIX
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = systemHandler_->applyFile(data[0].toString(), data[1].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
    #endif
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        // OcsHandler
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "OcsHandler::addProviders") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = ocsHandler_->addProviders(data[0].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "OcsHandler::removeProvider") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = ocsHandler_->removeProvider(data[0].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "OcsHandler::updateAllCategories") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = ocsHandler_->updateAllCategories(data[0].toBool());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "OcsHandler::updateCategories") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = ocsHandler_->updateCategories(data[0].toString(), data[1].toBool());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "OcsHandler::getContents") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = ocsHandler_->getContents(data[0].toString(), data[1].toString(),
                    data[2].toString(), data[3].toString(),
                    data[4].toString(), data[5].toString(), data[6].toInt(), data[7].toInt());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "OcsHandler::getContent") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = ocsHandler_->getContent(data[0].toString(), data[1].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        // ItemHandler
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ItemHandler::metadataSet") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            resultData[0] = itemHandler_->metadataSet();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ItemHandler::download") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            itemHandler_->download(data[0].toString(), data[1].toString(), data[2].toString(), data[3].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        else if (func == "ItemHandler::uninstall") {
    
    akiraohgaki's avatar
    akiraohgaki committed
            itemHandler_->uninstall(data[0].toString());
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        // Not supported
    
    akiraohgaki's avatar
    akiraohgaki committed
        else {
            return;
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        sendMessage(id, func, resultData);
    
    akiraohgaki's avatar
    akiraohgaki committed
    void WebSocketServer::sendMessage(const QString &id, const QString &func, const QJsonArray &data)
    
    akiraohgaki's avatar
    akiraohgaki committed
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        /* message object format
    
    akiraohgaki's avatar
    akiraohgaki committed
        {
            "id": "example",
            "func": "functionName",
    
    akiraohgaki's avatar
    akiraohgaki committed
            "data": ["value", 2, true]
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonObject object;
        object["id"] = id;
        object["func"] = func;
        object["data"] = data;
    
        QByteArray binaryMessage = qtlib::Json(object).toJson();
        QString textMessage = QString::fromUtf8(binaryMessage);
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        foreach (QWebSocket *wsClient, wsClients_) {
    
    akiraohgaki's avatar
    akiraohgaki committed
            wsClient->sendTextMessage(textMessage);
            //wsClient->sendBinaryMessage(binaryMessage);
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
    }