diff --git a/CMakeLists.txt b/CMakeLists.txt index defda8c..0c41b45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ find_package(Qt6 REQUIRED COMPONENTS Qml Quick QuickControls2 + Network ) set(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 396da3a..9e433b9 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(accordion-client PRIVATE Qt6::Gui Qt6::Quick Qt6::QuickControls2 + Qt6::Network accordion-common ) diff --git a/client/src/TcpClient.cpp b/client/src/TcpClient.cpp index 916b37b..759c04d 100644 --- a/client/src/TcpClient.cpp +++ b/client/src/TcpClient.cpp @@ -12,10 +12,10 @@ TcpClient::TcpClient(ConfigService* config, LoggerService* logger, QObject* pare } // connect sockets - connect(&socket_, &QTcpSocket::connected, this, &TcpClient::onConnected()); - connect(&socket_, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected()); - connect(&socket_, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead()); - connect(&socket_, &QTcpSocket::errorOccured, this, [this](QAbstractSocket::SocketError) { emit errorOccured(socket_.errorString()); }); // lazy + connect(&socket_, &QTcpSocket::connected, this, &TcpClient::onConnected); + connect(&socket_, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected); + connect(&socket_, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead); + connect(&socket_, &QTcpSocket::errorOccurred, this, [this](QAbstractSocket::SocketError) { emit errorOccurred(socket_.errorString()); }); // lazy logger_->log("TcpClient", LogFlag::Info, "TcpClient initialized."); @@ -25,11 +25,11 @@ TcpClient::~TcpClient() { // close port } -ErrorCode TcpClient::connect() { - socket_.connectToHost(configuration_.hostname, configuration_.port); +void TcpClient::connectServer() { + socket_.connectToHost(QString::fromStdString(configuration_.hostname), configuration_.port); } -ssize_t send(const char* data, size_t numBytes) { +void TcpClient::send(const char* data, size_t numBytes) { socket_.write(data, numBytes); } @@ -73,7 +73,7 @@ void TcpClient::handleMessage() { QByteArray message = receiveBuffer_.mid(kHeaderSize, msgSize); receiveBuffer_.remove(0, msgSize + kHeaderSize); - emit messageRecieved(message); + emit messageReceived(message); } diff --git a/client/src/TcpClient.hpp b/client/src/TcpClient.hpp index d09e9b8..4cfa55b 100644 --- a/client/src/TcpClient.hpp +++ b/client/src/TcpClient.hpp @@ -9,27 +9,33 @@ #include // TODO replace with chrono #include +#include +#include +#include + #include "common/config/ConfigService.hpp" #include "common/LoggerService.hpp" #include "common/ErrorCodes.hpp" #include "common/TcpBase.hpp" #include "config/ClientConfig.hpp" -class TcpClient : TcpBase { +class TcpClient : public QObject { + + Q_OBJECT public: - TcpClient(ConfigService* config, LoggerService* logger); + TcpClient(ConfigService* config, LoggerService* logger, QObject* parent = nullptr); ~TcpClient(); - void connect(); // asynchronous so no errorcode return - ssize_t send(const char* data, size_t numBytes); + void connectServer(); // asynchronous so no errorcode return + void send(const char* data, size_t numBytes); signals: void connected(); void disconnected(); void messageReceived(QByteArray message); - void error(QString error); + void errorOccurred(QString error); private slots: void onConnected(); @@ -40,8 +46,10 @@ private: void handleMessage(); + LoggerService* logger_; ClientParams configuration_; QTcpSocket socket_; - QByteArray receiveBuffer_[1024]; + QByteArray receiveBuffer_; + static constexpr size_t kHeaderSize = 8; // 4 bytes for length, 4 bytes for type }; diff --git a/client/src/config/ClientConfig.hpp b/client/src/config/ClientConfig.hpp index 5367bf2..20a8304 100644 --- a/client/src/config/ClientConfig.hpp +++ b/client/src/config/ClientConfig.hpp @@ -23,7 +23,10 @@ public: } setting.lookupValue("Hostname", params_->hostname); - setting.lookupValue("Port", params_->port); + + uint32_t portLong; + setting.lookupValue("Port", portLong); + params_->port = static_cast(portLong & 0xFFFF); return true; } diff --git a/client/src/main.cpp b/client/src/main.cpp index 7ee24b7..96a8f9b 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -25,14 +25,18 @@ int main(int argc, char* argv[]) { ConfigService config { centralConfigPath }; LoggerService logger {&config, "main"}; + TcpClient client {&config, &logger}; + + client.connectServer(); + const char data[] = "hi hello I would like some beans on toast"; + client.send(data, sizeof(data)); // attach backend gui components qmlRegisterType("accordion", 1, 0, "TimerComponent"); + engine.rootContext()->setContextProperty("tcpClient", &client); // alternative is engine.rootContext()->setContextProperty("timerComponent", &timerComponent); // which basically gives qml access to a singleton reference (qmlRegisterSingletonType is preferred) - //TcpClient client {&config, &logger}; - // load qml engine.load(QUrl::fromLocalFile("client/ui/Main.qml")); // ugh diff --git a/common/TcpBase.hpp b/common/TcpBase.hpp index edfdf65..5a61666 100644 --- a/common/TcpBase.hpp +++ b/common/TcpBase.hpp @@ -6,13 +6,11 @@ // TcpBase contains common tcp I/O operations for the tcp client and tcp server // Abstracts away the networking methods into an accordion common protocol (ACP) -class TcpBase : public QObject{ - - Q_OBJECT +class TcpBase { public: - TcpBase(LoggerService* logger, QObject* parent = nullptr); + TcpBase(LoggerService* logger); ~TcpBase(); // read from a tcp socket, blocking