Octave interface: SocketServer Major review

Simplified and made more readable. Hopefully more stable and robust.
This commit is contained in:
Jacob Støren
2013-10-04 14:29:11 +02:00
committed by JacobStoren
parent 3264520619
commit 12f3986d5f
2 changed files with 100 additions and 112 deletions

View File

@@ -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);
}
}

View File

@@ -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;