#include #include #include #include #include "items/item.h" #include "service.h" #include "tcpclient.h" TcpClient::TcpClient(QObject* parent): Service(parent), socket(new QTcpSocket(this)) { connect(socket, &QTcpSocket::readyRead, this, &TcpClient::socketReadyRead); } void TcpClient::sendJson(const QJsonObject& json) { QByteArray jsonData = QJsonDocument(json).toJson(); socket->write(QString("MSG JSON LEN " + QString::number(jsonData.size()) + "\n").toLatin1() + jsonData); } bool TcpClient::launch(const QHostAddress &address, quint16 port) { socket->connectToHost(address, port); return socket->waitForConnected(2000); } void TcpClient::processIncomeingJson(const QByteArray& jsonbytes) { QJsonDocument doc = QJsonDocument::fromJson(jsonbytes); QJsonObject json = doc.object(); QString type = json["MessageType"].toString(); if(type == "ItemUpdate") { QJsonArray data = json["Data"].toArray(); bool FullList = json["FullList"].toBool(false); std::vector> items; std::vector fieldChanges; for(QJsonValueRef itemjson : data) { QJsonObject jsonobject = itemjson.toObject(); std::shared_ptr item = Item::loadItem(jsonobject); if(item) { item->setLoaded(FullList); fieldChanges.push_back(item->loadWithChanges(jsonobject)); items.push_back(item); } } if(FullList && !items.empty()) { qDebug()<<"Client replaceing items"; requestReplaceItems(items); } else if(!items.empty()) { std::vector itemAddRequests; qDebug()<<"Client updateing items"; for(size_t i = 0; i < items.size(); i++) { ItemAddRequest request; request.type = ITEM_UPDATE_REMOTE; request.payload = items[i]; request.changes = fieldChanges[i]; itemAddRequests.push_back(request); qDebug()<<"Payload"<id(); } gotItems(itemAddRequests); } } else { Service::processIncomeingJson(jsonbytes); } } void TcpClient::processComand(const QByteArray& command) { if(command.startsWith("MSG JSON LEN ")) { state = STATE_RECV_JSON; recievebytes = command.mid(13).toLongLong(); } } void TcpClient::socketReadyRead() { buffer += socket->readAll(); bool remianing = true; while(remianing) { remianing = false; while(state == STATE_IDLE && buffer.contains('\n')) { size_t newlineIndex = buffer.indexOf('\n'); QByteArray command = buffer.left(newlineIndex); buffer.remove(0, newlineIndex+1); processComand(command); remianing = true; } if(state == STATE_RECV_JSON) { if(recievebytes <= buffer.size()) { QByteArray json = buffer.left(recievebytes); buffer.remove(0, recievebytes); recievebytes = 0; state = STATE_IDLE; processIncomeingJson(json); remianing = true; } } } } void TcpClient::itemUpdated(ItemUpdateRequest update) { if(update.type == ITEM_UPDATE_USER) { QJsonArray items; QJsonObject itemjson; update.payload.storeWithChanges(itemjson, update.changes); items.append(itemjson); QJsonObject json = createMessage("ItemUpdate", items); json["FullList"] = false; sendJson(json); } } void TcpClient::sensorEvent(Sensor sensor, sensor_update_type_t type) { // Only forward user-initiated sensor updates to the server // to prevent feedback loops with backend/remote updates if(type == SENSOR_UPDATE_USER) { Service::sensorEvent(sensor, type); } } TcpClient::~TcpClient() { delete socket; }