From 12f3986d5fe8e8fb2b4ce7dfb57911d6989b7e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 4 Oct 2013 14:29:11 +0200 Subject: [PATCH] Octave interface: SocketServer Major review Simplified and made more readable. Hopefully more stable and robust. --- .../SocketInterface/RiaSocketServer.cpp | 207 +++++++++--------- .../SocketInterface/RiaSocketServer.h | 5 +- 2 files changed, 100 insertions(+), 112 deletions(-) diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.cpp b/ApplicationCode/SocketInterface/RiaSocketServer.cpp index 84421947d4..5b09e649f9 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketServer.cpp @@ -106,54 +106,26 @@ unsigned short RiaSocketServer::serverPort() //-------------------------------------------------------------------------------------------------- void RiaSocketServer::slotNewClientConnection() { - // If we are currently handling a connection, just ignore the new one until the queue is empty. + // If we are currently handling a connection, just ignore the new one until the current one is disconnected. - if (m_currentClient != NULL) + if (m_currentClient && (m_currentClient->state() == QAbstractSocket::ConnectedState) ) { - if (m_currentClient->state() == QAbstractSocket::ConnectedState) - { - return; - } - else - { - if (m_currentCommand) - { - if (m_currentCommand->interpretMore(this, m_currentClient)) - { - delete m_currentCommand; - m_currentCommand = NULL; - } + return; + } - CVF_ASSERT(m_currentCommand == NULL); - } + // Read pending data from socket - terminateCurrentConnection(); + if (m_currentClient && m_currentCommand) + { + bool isFinshed = m_currentCommand->interpretMore(this, m_currentClient); + + if (!isFinshed) + { + m_errorMessageDialog->showMessage(tr("ResInsight SocketServer: \n") + tr("Warning : The command did not finish up correctly at the presence of a new one.")); } } - handlePendingIncomingConnectionRequests(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiaSocketServer::handleClientConnection(QTcpSocket* clientToHandle) -{ - CVF_ASSERT(clientToHandle != NULL); - CVF_ASSERT(m_currentClient == NULL); - CVF_ASSERT(m_currentCommand == NULL); - - m_currentClient = clientToHandle; - m_currentCommandSize = 0; - - connect(m_currentClient, SIGNAL(disconnected()), this, SLOT(slotCurrentClientDisconnected())); - - if (m_currentClient->bytesAvailable()) - { - this->readCommandFromOctave(); - } - - connect(m_currentClient, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); + handleNextPendingConnection(); } //-------------------------------------------------------------------------------------------------- @@ -195,26 +167,29 @@ RimCase* RiaSocketServer::findReservoir(int caseId) } //-------------------------------------------------------------------------------------------------- -/// +/// Reads the command name size, the command string and creates a new command object based on the string read. +/// Tries to interpret the command as well. +/// Returns whether the command actually was completely finished in one go. //-------------------------------------------------------------------------------------------------- -void RiaSocketServer::readCommandFromOctave() +bool RiaSocketServer::readCommandFromOctave() { QDataStream socketStream(m_currentClient); socketStream.setVersion(riOctavePlugin::qtDataStreamVersion); // If we have not read the currentCommandSize // read the size of the command if all the data is available + if (m_currentCommandSize == 0) { - if (m_currentClient->bytesAvailable() < (int)sizeof(qint64)) return; + if (m_currentClient->bytesAvailable() < (int)sizeof(qint64)) return false; socketStream >> m_currentCommandSize; } // Check if the complete command is available, return and whait for readyRead() if not - if (m_currentClient->bytesAvailable() < m_currentCommandSize) return; + if (m_currentClient->bytesAvailable() < m_currentCommandSize) return false; - // Now we can read the command + // Now we can read the command name QByteArray command = m_currentClient->read( m_currentCommandSize); QTextStream commandStream(command); @@ -229,27 +204,19 @@ void RiaSocketServer::readCommandFromOctave() CVF_ASSERT(args.size() > 0); + // Create the actual RiaSocketCommand object that will interpret the socket data + m_currentCommand = RiaSocketCommandFactory::instance()->create(args[0]); if (m_currentCommand) { bool finished = m_currentCommand->interpretCommand(this, args, socketStream); - if (finished) - { - delete m_currentCommand; - m_currentCommand = NULL; - - handlePendingIncomingConnectionRequests(); - return; - } + return finished; } else { - handlePendingIncomingConnectionRequests(); - m_errorMessageDialog->showMessage(tr("ResInsight SocketServer: \n") + tr("Unknown command: %1").arg(args[0].data())); - terminateCurrentConnection(); - return; + return true; } } @@ -261,19 +228,56 @@ void RiaSocketServer::slotCurrentClientDisconnected() { if (m_currentCommand) { - if (m_currentCommand->interpretMore(this, m_currentClient)) - { - delete m_currentCommand; - m_currentCommand = NULL; - } + // Make sure we read what can be read. + bool isFinished = m_currentCommand->interpretMore(this, m_currentClient); - /// What do we do here ? - CVF_ASSERT(m_currentCommand == NULL); + if (!isFinished) + { + m_errorMessageDialog->showMessage(tr("ResInsight SocketServer: \n") + tr("Warning : The command was interrupted and did not finish because the connection to octave disconnected.")); + } } - terminateCurrentConnection(); + handleNextPendingConnection(); +} - handlePendingIncomingConnectionRequests(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaSocketServer::slotReadyRead() +{ + if (m_currentCommand) + { + bool isFinished = m_currentCommand->interpretMore(this, m_currentClient); + + if (isFinished) + { + handleNextPendingConnection(); + } + } + else + { + bool isFinished = readCommandFromOctave(); + if (isFinished) + { + handleNextPendingConnection(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaSocketServer::setCurrentCaseId(int caseId) +{ + m_currentCaseId = caseId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RiaSocketServer::currentCaseId() const +{ + return m_currentCaseId; } //-------------------------------------------------------------------------------------------------- @@ -302,53 +306,38 @@ void RiaSocketServer::terminateCurrentConnection() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RiaSocketServer::slotReadyRead() +void RiaSocketServer::handleNextPendingConnection() { - if (m_currentCommand) + if (m_currentClient && (m_currentClient->state() == QAbstractSocket::ConnectedState) ) { - if (m_currentCommand->interpretMore(this, m_currentClient)) - { - delete m_currentCommand; - m_currentCommand = NULL; + return; + } - handlePendingIncomingConnectionRequests(); + terminateCurrentConnection(); + + QTcpSocket* clientToHandle = m_tcpServer->nextPendingConnection(); + if (clientToHandle) + { + CVF_ASSERT(m_currentClient == NULL); + CVF_ASSERT(m_currentCommand == NULL); + + m_currentClient = clientToHandle; + m_currentCommandSize = 0; + + connect(m_currentClient, SIGNAL(disconnected()), this, SLOT(slotCurrentClientDisconnected())); + connect(m_currentClient, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); + + if (m_currentClient->bytesAvailable()) + { + bool isFinished = this->readCommandFromOctave(); + if (isFinished) + { + // Call ourselves recursively until there are none left, or until it can not be processed in one go. + this->handleNextPendingConnection(); + } } } - else - { - readCommandFromOctave(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiaSocketServer::setCurrentCaseId(int caseId) -{ - m_currentCaseId = caseId; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -int RiaSocketServer::currentCaseId() const -{ - return m_currentCaseId; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiaSocketServer::handlePendingIncomingConnectionRequests() -{ - QTcpSocket* newClient = m_tcpServer->nextPendingConnection(); - if (newClient) - { - terminateCurrentConnection(); - - this->handleClientConnection(newClient); - } } diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.h b/ApplicationCode/SocketInterface/RiaSocketServer.h index 28c906177d..2f2971f502 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.h +++ b/ApplicationCode/SocketInterface/RiaSocketServer.h @@ -60,10 +60,9 @@ private slots: void slotCurrentClientDisconnected(); void slotReadyRead(); private: - void handleClientConnection( QTcpSocket* clientToHandle); void terminateCurrentConnection(); - void readCommandFromOctave(); - void handlePendingIncomingConnectionRequests(); + bool readCommandFromOctave(); + void handleNextPendingConnection(); private: QTcpServer* m_tcpServer;