Files
qt5-legatus-legacy/Lts/Proxies/HighLevelArchitecture/Hla_test_tool/web_socket_interface.cpp
T
2026-08-13 18:33:10 +02:00

251 lines
7.4 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Websocket Server to connect to NGSConnector
* $Id$
* $HeadURL$
* $Author$
*/
#include "ngs_handler.h"
#include "ngs_connector.h"
#include "web_socket_interface.h"
#include "ws_telegrams.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QTimer>
namespace HighLevelArchitecture
{
//
// class WsInterface
//
WsInterface::WsInterface(std::shared_ptr<NgsHandler> ngsHandler, QObject *parent)
: QObject(parent)
, m_wsServer(new QWebSocketServer(QStringLiteral("GNA"), QWebSocketServer::NonSecureMode, this))
, m_ngsHandler(ngsHandler)
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("HlaTestTool.WsInterface"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
WsInterface::~WsInterface()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
for (auto client : qAsConst(m_clients))
{
client->disconnect(this);
client->close();
}
qDeleteAll(m_clients);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool WsInterface::init(quint16 listenPort)
{
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
if (!m_wsServer->listen(QHostAddress::Any, listenPort))
{
WARNING_LOG(m_logger) << "Cannot listen on port " << listenPort << " - aborting";
return false;
}
DEBUG_LOG(m_logger) << "Listening on port " << listenPort;
connect(m_wsServer, &QWebSocketServer::newConnection,
this, &WsInterface::onNewConnection);
TRACE_LOG(m_logger) << LOGFUNCTION << " END, listenPort=" << listenPort;
return true;
}
void WsInterface::onNewConnection()
{
QWebSocket *clientSocket = m_wsServer->nextPendingConnection();
if (!clientSocket)
return;
connect(clientSocket, &QWebSocket::textMessageReceived,
this, &WsInterface::onTextMessageReceived);
connect(clientSocket, &QWebSocket::disconnected,
this, &WsInterface::onWebSocketDisconnected);
NOTICE_LOG(m_logger) << "Websocket connection established, ptr: " << clientSocket;
m_clients += clientSocket;
}
void WsInterface::onWebSocketDisconnected()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
QWebSocket *ws = qobject_cast<QWebSocket *>(sender());
if (!ws)
return;
NOTICE_LOG(m_logger) << "Websocket connection closed, ptr: " << ws;
m_clients.remove(ws);
ws->deleteLater();
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void WsInterface::onError(QAbstractSocket::SocketError error)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " Error occured, QAbstractSocket::SocketError = " << error;
}
void WsInterface::onTextMessageReceived(const QString &msg)
{
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, msg='" << msg << "'";
if (msg.isEmpty())
{
ERROR_LOG(m_logger) << "Empty message received";
return;
}
DEBUG_LOG(m_logger) << "incoming telegram: " << msg;
const QByteArray baJson = msg.toUtf8();
processMessage(baJson);
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
}
void WsInterface::processMessage(const QByteArray baJson)
{
NOTICE_LOG(m_logger) << LOGFUNCTION << " START";
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(baJson, &parseError);
if (parseError.error != QJsonParseError::NoError)
{
ERROR_LOG(m_logger) << "Could not parse JSON "
<< ". Reason: "
<< parseError.errorString()
<< "; baJson: '"
<< baJson << "'";
return;
}
NOTICE_LOG(m_logger) << "doc1 " << doc.toJson();
NOTICE_LOG(m_logger) << "doc2 " << doc.toJson(QJsonDocument::Compact) << "<<<";
const QJsonObject obj = doc.object();
const int typeId = obj.value(QStringLiteral("typeId")).toInt();
const QJsonObject data = obj.value(QStringLiteral("data")).toObject();
NOTICE_LOG(m_logger) << "Telegram with '" << typeId << "' received";
switch (typeId)
{
/*
python:
import websocket
import json
import time
ws = websocket.create_connection("ws://192.168.133.73:23456")
epoch_time = int(time.time())*1000
print(epoch_time)
d = { 'typeId' : 8011, 'data': {'objectId': 4711, 'name': 'myname', 'timestamp': epoch_time, 'activationTime': 12345678, 'isDeactivated': True, 'duration': 10, 'centerPoint':{'lat':52.477,'lon':11.597} } }
ws.send(json.dumps(d))
# d = { 'typeId' : 8010, 'data': {'objectId': 4711, 'name': 'removeAesObject', 'timestamp': epoch_time} }
ws.close()
*/
case 8001: // Dummy - neu definieren?
{
try
{
WsTelegramPosition pos = WsTelegramPosition::fromJson(data);
NOTICE_LOG(m_logger) << "type= " << pos.type();
NOTICE_LOG(m_logger) << "objectId= " << pos.objectId;
NOTICE_LOG(m_logger) << "name= '" << pos.name << "'";
NOTICE_LOG(m_logger) << "timestamp= " << pos.timestamp;
NOTICE_LOG(m_logger) << "lat= " << pos.position.lat;
NOTICE_LOG(m_logger) << "lon= " << pos.position.lon;
}
catch (const JsonException &ex)
{
ERROR_LOG(m_logger) << "Could not parse json telegram: "
<< ", error: " << ex.what();
}
break;
}
case 8010: // remove AesObj - neu definieren?
{
WsTelegramRemoveAesObject tele;
try
{
tele = WsTelegramRemoveAesObject::fromJson(data);
NOTICE_LOG(m_logger) << "type= " << tele.type();
NOTICE_LOG(m_logger) << "objectId= " << tele.objectId;
NOTICE_LOG(m_logger) << "name= '" << tele.name << "'";
NOTICE_LOG(m_logger) << "timestamp= " << tele.timestamp;
}
catch (const JsonException &ex)
{
ERROR_LOG(m_logger) << "Could not parse json telegram: "
<< ", error: " << ex.what();
return;
}
// WsTelegramXYObject to ngs/hla
if (m_ngsHandler && m_ngsHandler->ngsConnector())
m_ngsHandler->ngsConnector()->removeAesItem(tele.objectId);
break;
}
case 8011: // create/updateMineField - neu definieren?
{
WsTelegramMineFieldObject mf;
try
{
mf = WsTelegramMineFieldObject::fromJson(data);
NOTICE_LOG(m_logger) << "type= " << mf.type();
NOTICE_LOG(m_logger) << "objectId= " << mf.objectId;
NOTICE_LOG(m_logger) << "name= '" << mf.name << "'";
NOTICE_LOG(m_logger) << "timestamp= " << std::setprecision(15) << mf.timestamp;
NOTICE_LOG(m_logger) << "activationTime= " << std::setprecision(15) << mf.activationTime;
NOTICE_LOG(m_logger) << "duration= " << mf.duration;
NOTICE_LOG(m_logger) << "isDeactivated= " << mf.isDeactivated;
NOTICE_LOG(m_logger) << "lat= " << mf.area2D.centerPoint.lat << " - lon= " << mf.area2D.centerPoint.lon;
NOTICE_LOG(m_logger) << "width= " << mf.area2D.width << " - height= " << mf.area2D.height;
}
catch (const JsonException &ex)
{
ERROR_LOG(m_logger) << "Could not parse json telegram: "
<< ", error: " << ex.what();
return;
}
// WsTelegramXYObject to ngs/hla
if (m_ngsHandler && m_ngsHandler->ngsConnector())
m_ngsHandler->ngsConnector()->guezMineField(mf);
}
break;
default:
{
ERROR_LOG(m_logger) << "Telegram with typeId '" << typeId << "' not handled in switch"
<< ", doc= " << doc.toJson(QJsonDocument::Compact) << "<<<";
}
} // switch
}
} // HighLevelArchitecture