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() 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;
{ }
return;
}
else
{
if (m_currentCommand)
{
if (m_currentCommand->interpretMore(this, m_currentClient))
{
delete m_currentCommand;
m_currentCommand = NULL;
}
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(); handleNextPendingConnection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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()));
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -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); QDataStream socketStream(m_currentClient);
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion); socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
// If we have not read the currentCommandSize // If we have not read the currentCommandSize
// read the size of the command if all the data is available // read the size of the command if all the data is available
if (m_currentCommandSize == 0) if (m_currentCommandSize == 0)
{ {
if (m_currentClient->bytesAvailable() < (int)sizeof(qint64)) return; if (m_currentClient->bytesAvailable() < (int)sizeof(qint64)) return false;
socketStream >> m_currentCommandSize; socketStream >> m_currentCommandSize;
} }
// Check if the complete command is available, return and whait for readyRead() if not // 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); QByteArray command = m_currentClient->read( m_currentCommandSize);
QTextStream commandStream(command); QTextStream commandStream(command);
@@ -229,27 +204,19 @@ void RiaSocketServer::readCommandFromOctave()
CVF_ASSERT(args.size() > 0); CVF_ASSERT(args.size() > 0);
// Create the actual RiaSocketCommand object that will interpret the socket data
m_currentCommand = RiaSocketCommandFactory::instance()->create(args[0]); m_currentCommand = RiaSocketCommandFactory::instance()->create(args[0]);
if (m_currentCommand) if (m_currentCommand)
{ {
bool finished = m_currentCommand->interpretCommand(this, args, socketStream); bool finished = m_currentCommand->interpretCommand(this, args, socketStream);
if (finished) return finished;
{
delete m_currentCommand;
m_currentCommand = NULL;
handlePendingIncomingConnectionRequests();
return;
}
} }
else else
{ {
handlePendingIncomingConnectionRequests();
m_errorMessageDialog->showMessage(tr("ResInsight SocketServer: \n") + tr("Unknown command: %1").arg(args[0].data())); m_errorMessageDialog->showMessage(tr("ResInsight SocketServer: \n") + tr("Unknown command: %1").arg(args[0].data()));
terminateCurrentConnection(); return true;
return;
} }
} }
@@ -261,19 +228,56 @@ void RiaSocketServer::slotCurrentClientDisconnected()
{ {
if (m_currentCommand) if (m_currentCommand)
{ {
if (m_currentCommand->interpretMore(this, m_currentClient)) // Make sure we read what can be read.
{ bool isFinished = m_currentCommand->interpretMore(this, m_currentClient);
delete m_currentCommand;
m_currentCommand = NULL;
}
/// What do we do here ? if (!isFinished)
CVF_ASSERT(m_currentCommand == NULL); {
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;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -304,51 +308,36 @@ 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)) return;
{ }
delete m_currentCommand;
m_currentCommand = NULL;
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 slotCurrentClientDisconnected();
void slotReadyRead(); void slotReadyRead();
private: private:
void handleClientConnection( QTcpSocket* clientToHandle);
void terminateCurrentConnection(); void terminateCurrentConnection();
void readCommandFromOctave(); bool readCommandFromOctave();
void handlePendingIncomingConnectionRequests(); void handleNextPendingConnection();
private: private:
QTcpServer* m_tcpServer; QTcpServer* m_tcpServer;