Skip to content
Snippets Groups Projects
websocketserver.cpp 8.64 KiB
Newer Older
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
}

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());
        if (json.isValid()) {
akiraohgaki's avatar
akiraohgaki committed
            execRequest(json.toObject());
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);
        if (json.isValid()) {
akiraohgaki's avatar
akiraohgaki committed
            execRequest(json.toObject());
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::execRequest(const QJsonObject &request)
akiraohgaki's avatar
akiraohgaki committed
{
    /* request object format
    {
        "id": "example",
akiraohgaki's avatar
akiraohgaki committed
        "func": "functionName",
akiraohgaki's avatar
akiraohgaki committed
        "arg": ["value", 2, true]
akiraohgaki's avatar
akiraohgaki committed
    }
    */
    QString id = request["id"].toString();
akiraohgaki's avatar
akiraohgaki committed
    QString func = request["func"].toString();
    QJsonArray arg = request["arg"].toArray();
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    QJsonArray result;
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
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "WebSocketServer::isError") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = isError();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "WebSocketServer::errorString") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = errorString();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "WebSocketServer::serverUrl") {
akiraohgaki's avatar
akiraohgaki committed
        result[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
        result[0] = configHandler_->getAppConfigApplication();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::getAppConfigInstallTypes") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->getAppConfigInstallTypes();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::getUsrConfigApplication") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->getUsrConfigApplication();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigApplication") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigApplication(arg[0].toObject());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::getUsrConfigProviders") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->getUsrConfigProviders();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigProviders") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigProviders(arg[0].toObject());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::getUsrConfigCategories") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->getUsrConfigCategories();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigCategories") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigCategories(arg[0].toObject());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::getUsrConfigInstalledItems") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->getUsrConfigInstalledItems();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigInstalledItems") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigInstalledItems(arg[0].toObject());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigProvidersProvider") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigProvidersProvider(arg[0].toString(), arg[1].toObject());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::removeUsrConfigProvidersProvider") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->removeUsrConfigProvidersProvider(arg[0].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigCategoriesProvider") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigCategoriesProvider(arg[0].toString(), arg[1].toObject());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::removeUsrConfigCategoriesProvider") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->removeUsrConfigCategoriesProvider(arg[0].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigCategoriesInstallType") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigCategoriesInstallType(arg[0].toString(), arg[1].toString(), arg[2].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::setUsrConfigInstalledItemsItem") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->setUsrConfigInstalledItemsItem(arg[0].toString(), arg[1].toObject());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ConfigHandler::removeUsrConfigInstalledItemsItem") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = configHandler_->removeUsrConfigInstalledItemsItem(arg[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
        result[0] = systemHandler_->isUnix();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "SystemHandler::desktopEnvironment") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = systemHandler_->desktopEnvironment();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "SystemHandler::isApplicableType") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = systemHandler_->isApplicableType(arg[0].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "SystemHandler::applyFile") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = false;
akiraohgaki's avatar
akiraohgaki committed
#ifdef QTLIB_UNIX
akiraohgaki's avatar
akiraohgaki committed
        result[0] = systemHandler_->applyFile(arg[0].toString(), arg[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
        result[0] = ocsHandler_->addProviders(arg[0].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "OcsHandler::removeProvider") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = ocsHandler_->removeProvider(arg[0].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "OcsHandler::updateAllCategories") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = ocsHandler_->updateAllCategories(arg[0].toBool());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "OcsHandler::updateCategories") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = ocsHandler_->updateCategories(arg[0].toString(), arg[1].toBool());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "OcsHandler::getContents") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = ocsHandler_->getContents(arg[0].toString(), arg[1].toString(),
akiraohgaki's avatar
akiraohgaki committed
                arg[2].toString(), arg[3].toString(),
                arg[4].toString(), arg[5].toString(), arg[6].toInt(), arg[7].toInt());
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "OcsHandler::getContent") {
akiraohgaki's avatar
akiraohgaki committed
        result[0] = ocsHandler_->getContent(arg[0].toString(), arg[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
        result[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(arg[0].toString(), arg[1].toString(), arg[2].toString(), arg[3].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (func == "ItemHandler::uninstall") {
akiraohgaki's avatar
akiraohgaki committed
        itemHandler_->uninstall(arg[0].toString());
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    // Default
    else {
        return;
    }
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    QJsonObject response;
    response["id"] = id;
    response["func"] = func;
    response["result"] = result;
akiraohgaki's avatar
akiraohgaki committed
    sendResponse(response);
}

void WebSocketServer::sendResponse(const QJsonObject &response)
{
    /* response object format
    {
        "id": "example",
        "func": "functionName",
akiraohgaki's avatar
akiraohgaki committed
        "result": ["value", 2, true]
akiraohgaki's avatar
akiraohgaki committed
    }
    */

    foreach (QWebSocket *wsClient, wsClients_) {
        wsClient->sendTextMessage(QString(qtlib::Json(response).toJson()));
        //wsClient->sendBinaryMessage(qtlib::Json(response).toJson());
    }
akiraohgaki's avatar
akiraohgaki committed
}