#include "apism_tcp_client.h" #include #include #include ApismTcpClient::ApismTcpClient(const QString & hostname, const QString & port, QObject *parent) : QObject(parent) , hostname(hostname) , port(port) , responseTimerTimeoutCounter(0) { this->responseTimeoutTimer = new QTimer(this); this->responseTimeoutTimer->setInterval(10000); this->responseTimeoutTimer->setSingleShot(true); connect(this->responseTimeoutTimer, SIGNAL(timeout()), this, SLOT(onResponseTimeoutTimerTimeout())); socket = new QTcpSocket(this); connect(socket, SIGNAL(connected()), this, SLOT(onSocketConnected())); connect(socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected())); connect(socket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead())); connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(onSocketBytesWritten(qint64))); } void ApismTcpClient::connectToHost() { qCritical() << "ApismTcpClient::connectToHost(this->" << hostname << ", " << port << ")"; int portNumber = this->port.toInt(); this->socket->connectToHost(QHostAddress(this->hostname), portNumber); if (!socket->waitForConnected(10000)) { qCritical() << "ERROR IN WAIT FOR CONNECTED" << socket->errorString(); } else { qDebug() << "connected to" << hostname << ", " << port << ")"; } } void ApismTcpClient::connectToHost(const QString & hostname, const QString & port) { qCritical() << "ApismTcpClient::connectToHost(" << hostname << ", " << port << ")"; int portNumber = port.toInt(); socket->connectToHost(hostname, portNumber); } void ApismTcpClient::closeConnection() { socket->close(); } bool ApismTcpClient::isConnected() { bool result = false; QAbstractSocket::SocketState socketState = socket->state(); switch (socketState) { case QAbstractSocket::UnconnectedState: /* FALLTHRU */ case QAbstractSocket::HostLookupState: /* FALLTHRU */ case QAbstractSocket::ConnectingState: result = false; break; case QAbstractSocket::ConnectedState: /* FALLTHRU */ case QAbstractSocket::BoundState: result = true; break; case QAbstractSocket::ClosingState: /* FALLTHRU */ case QAbstractSocket::ListeningState: result = false; break; } return result; } void ApismTcpClient::sendData(const QByteArray & message) { qDebug() << "ApismTcpClient::send: " << message; this->sendQueue.enqueue(message); if (this->isConnected()) { qCritical() << "ApismTcpClient::send: connected, send" << message; this->private_sendData(); } else { qCritical() << "ApismTcpClient::send: not connected, connect"; this->connectToHost(); } } /** * @brief ApismTcpClient::private_sendData * * Precondition is that queue is not empty. */ void ApismTcpClient::private_sendData() { // take message from queue QByteArray ba = this->sendQueue.dequeue(); qDebug() << "ApismTcpClient::send: " << QString(ba); socket->write(ba); socket->flush(); // start timeoutTimer this->responseTimeoutTimer->start(); } void ApismTcpClient::onSocketConnected() { qInfo() << "ApismTcpClient: Connected!"; if (this->sendQueue.size() > 0) { this->private_sendData(); } } void ApismTcpClient::onSocketDisconnected() { qDebug() << "ApismTcpClient: Disconnected!"; qDebug() << " -> SocketErrorString: " << socket->errorString(); if (this->sendQueue.size() > 0) { this->connectToHost(); } } void ApismTcpClient::onSocketBytesWritten(qint64 bytes) { Q_UNUSED(bytes) } void ApismTcpClient::onSocketReadyRead() { QByteArray readData; // stop timeoutTimer this->responseTimeoutTimer->stop(); readData = socket->readAll(); qDebug() << "ISMAS received: " << QString(readData); emit this->receivedData(readData); //QCoreApplication::processEvents(); this->socket->close(); } void ApismTcpClient::onResponseTimeoutTimerTimeout() { if (this->sendQueue.size() == 0) { return; } emit this->responseTimeout(); qCritical() << "ApismTcpClient::onResponseTimeoutTimerTimeout() --> skip this message, send next command, if available."; // Try next command this->sendQueue.removeFirst(); if (this->sendQueue.size() > 0) this->private_sendData(); }