This commit is contained in:
maliakal_d 2019-06-12 10:40:56 +02:00
parent b922b79232
commit afb6d6bf3a
5 changed files with 141 additions and 129 deletions

View File

@ -65,9 +65,11 @@ set(HEADERS
include/qTabDebugging.h
include/qTabDeveloper.h
include/qTabMessages.h
../slsSupportLib/include/versionAPI.h
include/qServer.h
../slsDetectorSoftware/include
../slsSupportLib/include/versionAPI.h
../slsSupportLib/include/ServerSocket.h
../slsSupportLib/include/ServerInterface2.h
)
set(RESOURCES
include/icons.qrc

View File

@ -20,6 +20,28 @@ class qDefs : public QWidget {
#define GOODBYE -200
/** function enums */
enum qFuncNames {
QF_GET_DETECTOR_STATUS,
QF_START_ACQUISITION,
QF_STOP_ACQUISITION,
QF_START_AND_READ_ALL,
QF_EXIT_SERVER,
QF_NUM_FUNCTIONS
};
const char* getQFunctionNameFromEnum(enum qFuncNames func) {
switch (func) {
case QF_GET_DETECTOR_STATUS: return "QF_GET_DETECTOR_STATUS";
case QF_START_ACQUISITION: return "QF_START_ACQUISITION";
case QF_STOP_ACQUISITION: return "QF_STOP_ACQUISITION";
case QF_START_AND_READ_ALL: return "QF_START_AND_READ_ALL";
case QF_EXIT_SERVER: return "QF_EXIT_SERVER";
case QF_NUM_FUNCTIONS: return "QF_NUM_FUNCTIONS";
default: return "Unknown Function";
}
};
/** Success or FAIL */
enum { OK, FAIL };

View File

@ -1,14 +1,14 @@
#pragma once
#include "qDefs.h"
#include "ServerSocket.h"
class qDetectorMain;
class multiSlsDetector;
class ServerSocket;
class ServerInterface;
class ServerInterface2;
#include <vector>
#include <future>
class qServer : public QWidget, public virtual slsDetectorDefs {
class qServer : public QWidget {
Q_OBJECT
public:
@ -19,26 +19,24 @@ class qServer : public QWidget, public virtual slsDetectorDefs {
private:
void FunctionTable();
void DecodeFunction(ServerSocket *sock);
void ShutDownSockets();
void ServerThread(ServerSocket* sock);
void GetStatus(ServerSocket* sock);
void StartAcquisition(ServerSocket* sock);
void StopsAcquisition(ServerSocket* sock);
void Acquire(ServerSocket* sock);
void ExitServer(ServerSocket* sock);
/** function list */
typedef int (qServer::*some_func_t)(ServerSocket*);
typedef std::vector<some_func_t> sflist;
bool guiServerRunning;
bool threadStarted;
void DecodeFunction(sls::ServerInterface2 *socket);
void ServerThread(bool isControlServer);
void GetStatus(sls::ServerInterface2* socket);
void StartAcquisition(sls::ServerInterface2* socket);
void StopsAcquisition(sls::ServerInterface2* socket);
void Acquire(sls::ServerInterface2* socket);
void ExitServer(sls::ServerInterface2* socket);
void (qServer::*flist[qDefs::QF_NUM_FUNCTIONS])(sls::ServerInterface2 &socket);
qDetectorMain *mainTab;
bool tcpThreadCreated{false};
bool killTCPServerThread{false};
std::future<void> controlStatus;
std::future<void> stopStatus;
int controlPort;
int stopPort;
ServerSocket *controlSocket;
ServerSocket *stopSocket;
std::unique_ptr<sls::ServerSocket> controlSocket{nullptr};
std::unique_ptr<sls::ServerSocket> stopSocket{nullptr};
signals:
// to update the Listening to Gui check box

View File

@ -1,8 +1,7 @@
#include "qServer.h"
#include "qDefs.h"
#include "qDetectorMain.h"
#include "ServerSocket.h"
#include "ServerInterface2.h"
#include "string_utils.h"
#include <iostream>
@ -10,116 +9,114 @@
#include <future>
qServer::qServer(qDetectorMain *t)
: guiServerRunning(false), threadStarted(false), mainTab(t),
controlPort(DEFAULT_GUI_PORTNO), stopPort(DEFAULT_GUI_PORTNO + 1),
controlSocket(nullptr), stopSocket(nullptr) {
: mainTab(t), controlPort(DEFAULT_GUI_PORTNO), stopPort(DEFAULT_GUI_PORTNO + 1),
controlSocket(nullptr), stopSocket(nullptr) {
FILE_LOG(logDEBUG) << "Client Server ready";
}
qServer::~qServer() {}
void qServer::FunctionTable() {
sflist.push_back(&qServer::GetStatus);
sflist.push_back(&qServer::StartAcquisition);
sflist.push_back(&qServer::StopsAcquisition);
sflist.push_back(&qServer::Acquire);
sflist.push_back(&qServer::ExitServer);
flist[qDefs::QF_GET_DETECTOR_STATUS] = &qServer::GetStatus;
flist[qDefs::QF_START_ACQUISITION] = &qServer::StartAcquisition;
flist[qDefs::QF_STOP_ACQUISITION] = &qServer::StopsAcquisition;
flist[qDefs::QF_START_AND_READ_ALL] = &qServer::Acquire;
flist[qDefs::QF_EXIT_SERVER] = &qServer::ExitServer;
}
int qServer::DecodeFunction(ServerSocket *sock) {
int ret = qDefs::FAIL;
int fnum = 0;
int n = sock->ReceiveDataOnly(&fnum, sizeof(fnum));
if (n <= 0) {
FILE_LOG(logDEBUG3) << "Received " << n << " bytes";
throw sls::RuntimeError("Could not read socket");
void qServer::DecodeFunction(sls::ServerInterface2 *socket) {
qFuncNames fnum;
socket.Receive(fnum);
if (fnum < 0 || fnum >= QF_NUM_FUNCTIONS) {
throw RuntimeError("Unrecognized Function enum " + std::to_string(fnum) + "\n");
}
// unrecognized function
if (fnum < 0 && fnum >= qDefs::NUM_GUI_FUNCS) {
ret = qDefs::FAIL;
char mess[MAX_STR_LENGTH] = {};
sls::strcpy_safe(mess, "Unrecognized function");
// will throw an exception
sock->SendResult(ret, nullptr, 0, mess);
}
// calling function
FILE_LOG(logDEBUG1) << "calling function fnum: " << fnum;
ret = (this->*sflist[fnum])(sock);
return ret;
}
void qServer::ShutDownSockets() {
guiServerRunning = false;
if (controlSocket) {
controlSocket->shutDownSocket();
delete controlSocket;
controlSocket = nullptr;
}
if (stopSocket) {
stopSocket->shutDownSocket();
delete stopSocket;
stopSocket = nullptr;
}
FILE_LOG(logDEBUG1) << "calling function fnum: " << fnum << " ("
<< slsDetectorDefs::getQFunctionNameFromEnum(fnum) << ")";
(this->*flist[fnum])(socket);
FILE_LOG(logDEBUG1) << "Function " << getQFunctionNameFromEnum(fnum) << " finished";
}
void qServer::CreateServers() {
if (!guiServerRunning) {
if (!tcpThreadCreated) {
FILE_LOG(logINFO) << "Starting Gui Servers";
guiServerRunning = true;
tcpThreadCreated = true;
try {
// start control server
controlSocket = new ServerSocket(controlPort);
std::async(std::launch::async, ServerThread, controlSocket);
FILE_LOG(logDEBUG)
<< "Gui control server thread created successfully.";
controlStatus = std::async(std::launch::async, ServerThread, true);
FILE_LOG(logDEBUG) << "Gui control server thread created successfully.";
// start stop server
stopSocket = new ServerSocket(stopPort);
std::async(std::launch::async, ServerThread, stopSocket);
FILE_LOG(logDEBUG)
<< "Gui stop server thread created successfully.";
stopStatus = std::async(std::launch::async, ServerThread, false);
FILE_LOG(logDEBUG) << "Gui stop server thread created successfully.";
} catch (...) {
ShutDownSockets();
std::string message = "Can't create gui control server thread";
FILE_LOG(logERROR) << message;
std::string mess = "Could not create Gui TCP servers";
FILE_LOG(logERROR) << mess;
qDefs::Message(qDefs::WARNING, message, "qServer::CreateServers");
DestroyServers();
}
}
}
void qServer::DestroyServers() {
if (guiServerRunning) {
FILE_LOG(logINFO) << "Stopping Gui Servers";
ShutDownSockets();
if (tcpThreadCreated) {
FILE_LOG(logINFO) << "Shutting down Gui TCP Sockets";
killTCPServerThread = true;
if (controlSocket)
controlSocket->shutDownSocket();
if (stopSocket)
stopSocket->shutDownSocket();
controlStatus.wait();
stopStatus.wait();
tcpThreadCreated = false;
killTCPServerThread = false;
FILE_LOG(logDEBUG) << "Server threads stopped successfully.";
}
}
void qServer::ServerThread(ServerSocket* sock) {
FILE_LOG(logDEBUG) << "Starting Gui Server at port " << sock->getPort();
void qServer::ServerThread(isControlServer) {
sls::ServerSocket* sock = nullptr;
if (isControl) {
FILE_LOG(logDEBUG) << "Starting Gui Server (Control port: " << controlPort << ")";
controlSocket = sls::make_unique<sls::ServerSocket>(controlPort);
sock = controlSocket;
} else {
FILE_LOG(logDEBUG) << "Starting Gui Server (Stop port: " << stopPort << ")";
stopSocket = sls::make_unique<sls::ServerSocket>(stopPort);
sock = stopSocket;
}
while (guiServerRunning)) {
while (true) {
try{
sock->accept();
if (DecodeFunction(sock) == GOODBYE) {
guiServerRunning = false;
auto socket = sock->accept();
try{
decode_function(socket);
} catch(const sls::NonCriticalError &e) {
if (strstr(e.what(), "exit")) {
FILE_LOG(logINFO) << "Exiting " << (isControlServer ? "Control" : "Stop") << "Server";
break;
}
char mess[MAX_STR_LENGTH];
sls::strcpy_safe(mess, e.what());
socket.Send(FAIL);
socket.Send(mess);
}
sock->close();
}
// any fails will throw an exception, which will be displayed at client side. Ignore here
catch (...) {}
} catch (const sls::NonCriticalError &e) {
FILE_LOG(logERROR) << "Accept failed";
}
// Destroy server
if (killTCPServerThread) {
FILE_LOG(logINFO) << "Exiting " << (isControlServer ? "Control" : "Stop") << "Server";
break;
}
}
FILE_LOG(logDEBUG) << "Stopped gui server thread";
// stop port is closed last
if (sock->getPort() == stopPort)
emit ServerStoppedSignal();
}
int qServer::GetStatus(ServerSocket* sock) {
void qServer::GetStatus(sls::ServerInterface2* socket) {
slsDetectorDefs::runStatus status = slsDetectorDefs::ERROR;
int progress = 0;
if (myMainTab->isPlotRunning())
@ -129,43 +126,36 @@ int qServer::GetStatus(ServerSocket* sock) {
progress = myMainTab->GetProgress();
int ret = qDefs::OK
int retvals[2] = {static_cast<int>(retval), progress};
sock->SendResult(ret, retvals, sizeof(retvals), nullptr);
return ret;
int retvals[2] = {static_cast<int>(status), progress};
socket.SendResult(retvals);
}
int qServer::StartAcquisition(ServerSocket* sock) {
char mess[MAX_STR_LENGTH] = {};
sls::strcpy_safe(mess, "Could not start acquistion in Gui");
int ret = myMainTab->StartStopAcquisitionFromClient(true);
sock->SendResult(ret, nullptr, 0, mess);
return ret;
void qServer::StartAcquisition(sls::ServerInterface2* socket) {
if (myMainTab->StartStopAcquisitionFromClient(true) == slsDetectorDefs::FAIL) {
throw sls::NonCriticalError("Could not start acquistion in Gui");
}
socket.Send(slsDetectorDefs::OK);
}
int qServer::StopsAcquisition(ServerSocket* sock) {
char mess[MAX_STR_LENGTH] = {};
sls::strcpy_safe(mess, "Could not stop acquistion in Gui");
int ret = myMainTab->StartStopAcquisitionFromClient(false);
sock->SendResult(ret, nullptr, 0, mess);
return ret;
void qServer::StopsAcquisition(sls::ServerInterface2* socket) {
if (myMainTab->StartStopAcquisitionFromClient(false) == slsDetectorDefs::FAIL) {
throw sls::NonCriticalError("Could not stop acquistion in Gui");
}
socket.Send(slsDetectorDefs::OK);
}
int qServer::Acquire(ServerSocket* sock) {
char mess[MAX_STR_LENGTH] = {};
sls::strcpy_safe(mess, "Could not start blocking acquistion in Gui");
int ret = myMainTab->StartStopAcquisitionFromClient(true);
void qServer::Acquire(sls::ServerInterface2* socket) {
if (myMainTab->StartStopAcquisitionFromClient(true) == slsDetectorDefs::FAIL) {
throw sls::NonCriticalError("Could not start blocking acquistion in Gui");
}
// blocking
usleep(5000);
while (myMainTab->isPlotRunning())
;
sock->SendResult(ret, nullptr, 0, mess);
return ret;
while (myMainTab->isPlotRunning()) {
usleep(5000);
}
socket.Send(slsDetectorDefs::OK);
}
int qServer::ExitServer(ServerSocket* sock) {
DestroyServers();
int ret = qDefs::OK;
sock->SendResult(ret, nullptr, 0, mess);
return GOODBYE;
void qServer::ExitServer(sls::ServerInterface2* socket) {
throw sls::NonCriticalError("Server exited");
}

View File

@ -128,7 +128,7 @@ void slsReceiverTCPIPInterface::startTCPServer() {
pthread_exit(nullptr);
}
} catch (const RuntimeError &e) {
std::cout << "Accept failed\n";
FILE_LOG(logERROR) << "Accept failed";
}
// if user entered exit