144 lines
3.4 KiB
C++
144 lines
3.4 KiB
C++
#include <QTcpSocket>
|
|
#include <QJsonDocument>
|
|
#include <QJsonArray>
|
|
#include <iostream>
|
|
|
|
#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<std::shared_ptr<Item>> items;
|
|
std::vector<ItemFieldChanges> fieldChanges;
|
|
for(QJsonValueRef itemjson : data)
|
|
{
|
|
QJsonObject jsonobject = itemjson.toObject();
|
|
std::shared_ptr<Item> 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<ItemAddRequest> 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"<<request.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;
|
|
}
|