diff --git a/include/api/JsonAPI.h b/include/api/JsonAPI.h index 60b092f5..37349631 100644 --- a/include/api/JsonAPI.h +++ b/include/api/JsonAPI.h @@ -50,6 +50,8 @@ public: /// void initialize(); + QSharedPointer JsonAPI::getCallBack() const; + public slots: private slots: @@ -82,7 +84,7 @@ signals: /// /// Signal emits with the reply message provided with handleMessage() /// - void callbackMessage(QJsonObject); + void callbackReady(QJsonObject); /// /// Signal emits whenever a JSON-message should be forwarded diff --git a/include/api/JsonCallbacks.h b/include/api/JsonCallbacks.h index a5c14ce4..14b30479 100644 --- a/include/api/JsonCallbacks.h +++ b/include/api/JsonCallbacks.h @@ -93,7 +93,7 @@ signals: /// @brief Emits whenever a new json mesage callback is ready to send /// @param The JsonObject message /// - void newCallback(QJsonObject); + void callbackReady(QJsonObject); private slots: /// @@ -182,6 +182,8 @@ private: /// construct callback msg void doCallback(Subscription::Type cmd, const QVariant& data); + void doCallback(Subscription::Type cmd, const QJsonArray& data); + void doCallback(Subscription::Type cmd, const QJsonObject& data); Logger *_log; Hyperion* _hyperion; diff --git a/libsrc/api/JsonAPI.cpp b/libsrc/api/JsonAPI.cpp index 52e4c6af..ac5fcdc1 100644 --- a/libsrc/api/JsonAPI.cpp +++ b/libsrc/api/JsonAPI.cpp @@ -85,6 +85,11 @@ JsonAPI::JsonAPI(QString peerAddress, Logger *log, bool localConnection, QObject _jsonCB = QSharedPointer(new JsonCallbacks( _log, _peerAddress, parent)); } +QSharedPointer JsonAPI::getCallBack() const +{ + return _jsonCB; +} + void JsonAPI::initialize() { // init API, REQUIRED! @@ -97,9 +102,6 @@ void JsonAPI::initialize() // listen for killed instances connect(_instanceManager, &HyperionIManager::instanceStateChanged, this, &JsonAPI::handleInstanceStateChange); - // pipe callbacks from subscriptions to parent - connect(_jsonCB.data(), &JsonCallbacks::newCallback, this, &JsonAPI::callbackMessage); - // notify hyperion about a jsonMessageForward if (_hyperion != nullptr) { @@ -1537,7 +1539,7 @@ void JsonAPI::sendSuccessReply(const JsonApiCommand& cmd) void JsonAPI::sendSuccessReply(const QString &command, int tan, InstanceCmd::Type isInstanceCmd) { - emit callbackMessage(getBasicCommandReply(true, command, tan , isInstanceCmd)); + emit callbackReady(getBasicCommandReply(true, command, tan , isInstanceCmd)); } void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const JsonApiCommand& cmd) @@ -1572,7 +1574,7 @@ void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QS reply["errorData"] = errorsArray; } - emit callbackMessage(reply); + emit callbackReady(reply); } void JsonAPI::sendErrorReply(const QString &error, const JsonApiCommand& cmd) @@ -1601,7 +1603,7 @@ void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetai reply["errorData"] = errorsArray; } - emit callbackMessage(reply); + emit callbackReady(reply); } void JsonAPI::sendNewRequest(const QJsonValue &infoData, const JsonApiCommand& cmd) @@ -1621,7 +1623,7 @@ void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command, request["info"] = infoData; - emit callbackMessage(request); + emit callbackReady(request); } void JsonAPI::sendNoAuthorization(const JsonApiCommand& cmd) diff --git a/libsrc/api/JsonCallbacks.cpp b/libsrc/api/JsonCallbacks.cpp index 0e156727..44369cac 100644 --- a/libsrc/api/JsonCallbacks.cpp +++ b/libsrc/api/JsonCallbacks.cpp @@ -282,22 +282,43 @@ QStringList JsonCallbacks::getSubscribedCommands() const } void JsonCallbacks::doCallback(Subscription::Type cmd, const QVariant& data) +{ + if (data.userType() == QMetaType::QJsonArray) + { + doCallback(cmd, data.toJsonArray()); + } + else + { + doCallback(cmd, data.toJsonObject()); + } +} + +void JsonCallbacks::doCallback(Subscription::Type cmd, const QJsonArray& data) { QJsonObject obj; obj["command"] = Subscription::toString(cmd); if (Subscription::isInstanceSpecific(cmd)) { - obj["instance"] = _hyperion->getInstanceIndex(); + obj.insert("instance", _hyperion->getInstanceIndex()); } + obj.insert("data", data); - if (data.userType() == QMetaType::QJsonArray) { - obj["data"] = data.toJsonArray(); - } else { - obj["data"] = data.toJsonObject(); + emit callbackReady(obj); +} + +void JsonCallbacks::doCallback(Subscription::Type cmd, const QJsonObject& data) +{ + QJsonObject obj; + obj["command"] = Subscription::toString(cmd); + + if (Subscription::isInstanceSpecific(cmd)) + { + obj.insert("instance", _hyperion->getInstanceIndex()); } + obj.insert("data", data); - emit newCallback(obj); + emit callbackReady(obj); } void JsonCallbacks::handleComponentState(hyperion::Components comp, bool state) @@ -306,7 +327,7 @@ void JsonCallbacks::handleComponentState(hyperion::Components comp, bool state) data["name"] = componentToIdString(comp); data["enabled"] = state; - doCallback(Subscription::ComponentsUpdate, QVariant(data)); + doCallback(Subscription::ComponentsUpdate, data); } void JsonCallbacks::handlePriorityUpdate(int currentPriority, const PriorityMuxer::InputsMap& activeInputs) @@ -315,7 +336,7 @@ void JsonCallbacks::handlePriorityUpdate(int currentPriority, const PriorityMuxe data["priorities"] = JsonInfo::getPrioritiestInfo(currentPriority, activeInputs); data["priorities_autoselect"] = _hyperion->sourceAutoSelectEnabled(); - doCallback(Subscription::PrioritiesUpdate, QVariant(data)); + doCallback(Subscription::PrioritiesUpdate, data); } void JsonCallbacks::handleImageToLedsMappingChange(int mappingType) @@ -323,7 +344,7 @@ void JsonCallbacks::handleImageToLedsMappingChange(int mappingType) QJsonObject data; data["imageToLedMappingType"] = ImageProcessor::mappingTypeToStr(mappingType); - doCallback(Subscription::ImageToLedMappingUpdate, QVariant(data)); + doCallback(Subscription::ImageToLedMappingUpdate, data); } void JsonCallbacks::handleAdjustmentChange() @@ -335,7 +356,7 @@ void JsonCallbacks::handleVideoModeChange(VideoMode mode) { QJsonObject data; data["videomode"] = QString(videoMode2String(mode)); - doCallback(Subscription::VideomodeUpdate, QVariant(data)); + doCallback(Subscription::VideomodeUpdate, data); } #if defined(ENABLE_EFFECTENGINE) @@ -343,29 +364,29 @@ void JsonCallbacks::handleEffectListChange() { QJsonObject effects; effects["effects"] = JsonInfo::getEffects(_hyperion); - doCallback(Subscription::EffectsUpdate, QVariant(effects)); + doCallback(Subscription::EffectsUpdate, effects); } #endif void JsonCallbacks::handleSettingsChange(settings::type type, const QJsonDocument& data) { - QJsonObject dat; + QJsonObject obj; if(data.isObject()) { - dat[typeToString(type)] = data.object(); + obj[typeToString(type)] = data.object(); } else { - dat[typeToString(type)] = data.array(); + obj[typeToString(type)] = data.array(); } - doCallback(Subscription::SettingsUpdate, QVariant(dat)); + doCallback(Subscription::SettingsUpdate, obj); } void JsonCallbacks::handleLedsConfigChange(settings::type type, const QJsonDocument& data) { if(type == settings::LEDS) { - QJsonObject dat; - dat[typeToString(type)] = data.array(); - doCallback(Subscription::LedsUpdate, QVariant(dat)); + QJsonObject obj; + obj[typeToString(type)] = data.array(); + doCallback(Subscription::LedsUpdate, obj); } } @@ -385,7 +406,7 @@ void JsonCallbacks::handleTokenChange(const QVector sub["last_use"] = entry.lastUse; arr.push_back(sub); } - doCallback(Subscription::TokenUpdate, QVariant(arr)); + doCallback(Subscription::TokenUpdate, arr); } void JsonCallbacks::handleLedColorUpdate(const std::vector &ledColors) @@ -393,13 +414,16 @@ void JsonCallbacks::handleLedColorUpdate(const std::vector &ledColors) QJsonObject result; QJsonArray leds; - for (const auto &color : ledColors) + // Avoid copying by appending RGB values directly + for (const auto& color : ledColors) { - leds << QJsonValue(color.red) << QJsonValue(color.green) << QJsonValue(color.blue); + leds.append(QJsonValue(color.red)); + leds.append(QJsonValue(color.green)); + leds.append(QJsonValue(color.blue)); } result["leds"] = leds; - doCallback(Subscription::LedColorsUpdate, QVariant(result)); + doCallback(Subscription::LedColorsUpdate, result); } void JsonCallbacks::handleImageUpdate(const Image &image) @@ -413,7 +437,7 @@ void JsonCallbacks::handleImageUpdate(const Image &image) QJsonObject result; result["image"] = "data:image/jpg;base64," + QString(byteArray.toBase64()); - doCallback(Subscription::ImageUpdate, QVariant(result)); + doCallback(Subscription::ImageUpdate, result); } void JsonCallbacks::handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &msg) @@ -445,7 +469,7 @@ void JsonCallbacks::handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &msg) } result.insert("messages", messageArray); - doCallback(Subscription::LogMsgUpdate, QVariant(result)); + doCallback(Subscription::LogMsgUpdate, result); } void JsonCallbacks::handleEventUpdate(const Event &event) @@ -454,6 +478,6 @@ void JsonCallbacks::handleEventUpdate(const Event &event) result["event"] = eventToString(event); - doCallback(Subscription::EventUpdate, QVariant(result)); + doCallback(Subscription::EventUpdate, result); } diff --git a/libsrc/jsonserver/JsonClientConnection.cpp b/libsrc/jsonserver/JsonClientConnection.cpp index 8af1346a..cdd2fe8a 100644 --- a/libsrc/jsonserver/JsonClientConnection.cpp +++ b/libsrc/jsonserver/JsonClientConnection.cpp @@ -1,6 +1,7 @@ // project includes #include "JsonClientConnection.h" #include +#include // qt inc #include @@ -17,8 +18,9 @@ JsonClientConnection::JsonClientConnection(QTcpSocket *socket, bool localConnect // create a new instance of JsonAPI _jsonAPI = new JsonAPI(socket->peerAddress().toString(), _log, localConnection, this); // get the callback messages from JsonAPI and send it to the client - connect(_jsonAPI, &JsonAPI::callbackMessage, this , &JsonClientConnection::sendMessage); + connect(_jsonAPI, &JsonAPI::callbackReady, this , &JsonClientConnection::sendMessage); connect(_jsonAPI, &JsonAPI::forceClose, this , [&](){ _socket->close(); } ); + connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &JsonClientConnection::sendMessage); _jsonAPI->initialize(); } @@ -47,7 +49,8 @@ void JsonClientConnection::readRequest() qint64 JsonClientConnection::sendMessage(QJsonObject message) { QJsonDocument writer(message); - QByteArray data = writer.toJson(QJsonDocument::Compact) + "\n"; + QByteArray data = writer.toJson(QJsonDocument::Compact); + data.append('\n'); if (!_socket || (_socket->state() != QAbstractSocket::ConnectedState)) return 0; return _socket->write(data.data(), data.size()); diff --git a/libsrc/webserver/WebJsonRpc.cpp b/libsrc/webserver/WebJsonRpc.cpp index 345215d9..a0edf719 100644 --- a/libsrc/webserver/WebJsonRpc.cpp +++ b/libsrc/webserver/WebJsonRpc.cpp @@ -5,6 +5,7 @@ #include "QtHttpClientWrapper.h" #include +#include WebJsonRpc::WebJsonRpc(QtHttpRequest* request, QtHttpServer* server, bool localConnection, QtHttpClientWrapper* parent) : QObject(parent) @@ -14,8 +15,10 @@ WebJsonRpc::WebJsonRpc(QtHttpRequest* request, QtHttpServer* server, bool localC { const QString client = request->getClientInfo().clientAddress.toString(); _jsonAPI = new JsonAPI(client, _log, localConnection, this, true); - connect(_jsonAPI, &JsonAPI::callbackMessage, this, &WebJsonRpc::handleCallback); + connect(_jsonAPI, &JsonAPI::callbackReady, this, &WebJsonRpc::sendCallbackMessage); connect(_jsonAPI, &JsonAPI::forceClose, [&]() { _wrapper->closeConnection(); _stopHandle = true; }); + connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &WebJsonRpc::sendCallbackMessage); + _jsonAPI->initialize(); } @@ -31,7 +34,7 @@ void WebJsonRpc::handleMessage(QtHttpRequest* request) } } -void WebJsonRpc::handleCallback(QJsonObject obj) +void WebJsonRpc::sendCallbackMessage(QJsonObject obj) { // guard against wrong callbacks; TODO: Remove when JSONAPI is more solid if(!_unlocked) return; diff --git a/libsrc/webserver/WebJsonRpc.h b/libsrc/webserver/WebJsonRpc.h index 2eed7ed8..695bcb14 100644 --- a/libsrc/webserver/WebJsonRpc.h +++ b/libsrc/webserver/WebJsonRpc.h @@ -26,5 +26,5 @@ private: bool _unlocked = false; private slots: - void handleCallback(QJsonObject obj); + void sendCallbackMessage(QJsonObject obj); }; diff --git a/libsrc/webserver/WebSocketClient.cpp b/libsrc/webserver/WebSocketClient.cpp index 3cf8adbc..a4eab0e3 100644 --- a/libsrc/webserver/WebSocketClient.cpp +++ b/libsrc/webserver/WebSocketClient.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -24,9 +25,11 @@ WebSocketClient::WebSocketClient(QtHttpRequest* request, QTcpSocket* sock, bool // Json processor _jsonAPI.reset(new JsonAPI(client, _log, localConnection, this)); - connect(_jsonAPI.get(), &JsonAPI::callbackMessage, this, &WebSocketClient::sendMessage); + connect(_jsonAPI.get(), &JsonAPI::callbackReady, this, &WebSocketClient::sendMessage); connect(_jsonAPI.get(), &JsonAPI::forceClose, this,[this]() { this->sendClose(CLOSECODE::NORMAL); }); + connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &WebSocketClient::sendMessage); + connect(this, &WebSocketClient::handleMessage, _jsonAPI.get(), &JsonAPI::handleMessage); Debug(_log, "New connection from %s", QSTRING_CSTR(client));