add BufferedReads, add AutoStart and KeepAlive command line options

This commit is contained in:
Syping 2024-05-07 17:29:23 +02:00
parent d37369ad4f
commit 1ddc4ff755
5 changed files with 78 additions and 41 deletions

View file

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.5)
project(smsub LANGUAGES CXX VERSION 0.8)
project(smsub LANGUAGES CXX VERSION 0.9)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

View file

@ -22,8 +22,8 @@
#include "SMSubProcess.h"
#include "smsub.h"
SMSubProcess::SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int &termTimeout, const bool &keepAlive) :
termTimeout(termTimeout), keepAlive(keepAlive)
SMSubProcess::SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int termTimeout, const bool buffReads, const bool keepAlive) :
termTimeout(termTimeout), buffReads(buffReads), keepAlive(keepAlive)
{
// Set process executable, arguments and working directory
process.setProgram(executable);
@ -33,7 +33,7 @@ SMSubProcess::SMSubProcess(const QString &executable, const QStringList &argumen
// manage input channel
process.setInputChannelMode(QProcess::ManagedInputChannel);
// stdout and stderr in same IO stream
// stdout and stderr in same I/O stream
process.setProcessChannelMode(QProcess::MergedChannels);
// Connect process signal handlers
@ -58,14 +58,17 @@ void SMSubProcess::readyRead()
QTextStream(stderr) << "Subprocess I/O RR!" << smsub_endl;
#endif
// Read process output and emit event
#ifdef SMSUB_BUFFERED_READS
if (buffReads) {
while (process.bytesAvailable()) {
#ifdef SMSUB_IODEBUG
QTextStream(stderr) << "Subprocess I/O W!" << smsub_endl;
#endif
const QByteArray readData = process.read(1024);
if (!readData.isEmpty())
emit outputWritten(readData);
#else
}
}
else {
while (process.canReadLine()) {
#ifdef SMSUB_IODEBUG
QTextStream(stderr) << "Subprocess I/O WL!" << smsub_endl;
@ -73,7 +76,7 @@ void SMSubProcess::readyRead()
const QByteArray readData = process.readLine().trimmed();
emit outputWritten(readData + '\n');
}
#endif
}
}
void SMSubProcess::processError(QProcess::ProcessError error)

View file

@ -26,11 +26,12 @@ class SMSubProcess : public QObject
{
Q_OBJECT
public:
SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int &termTimeout = 60000, const bool &keepAlive = false);
SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int termTimeout = 60000, const bool buffReads = false, const bool keepAlive = false);
private:
QProcess process;
int termTimeout;
bool buffReads;
bool keepAlive;
public slots:

View file

@ -79,7 +79,7 @@ void SMSubServer::newConnection()
QObject::connect(webSocket, &QWebSocket::disconnected, this, &SMSubServer::deleteSocket);
webSocket->sendBinaryMessage(QString("SMSub Version %1\n").arg(QCoreApplication::applicationVersion()).toUtf8());
socket = webSocket;
QTextStream(stderr) << QString("WebSocket %1:%2 connected!").arg(webSocket->peerName(), QString::number(webSocket->peerPort())) << smsub_endl;
QTextStream(stderr) << QString("WebSocket %1:%2 connected!").arg(webSocket->peerAddress().toString(), QString::number(webSocket->peerPort())) << smsub_endl;
}
else {
// Just for being sure
@ -101,25 +101,26 @@ bool SMSubServer::messageReceived(QObject *socket, const QByteArray &message)
// Only allow commands being sent if authenticated
const bool isAuthenticated = socket->property("Authenticated").toBool();
if (Q_LIKELY(isAuthenticated)) {
if (message.startsWith("+dbg")) {
if (message == "+dbg") {
socket->setProperty("ReceiveDbgMsg", true);
sendMessage(socket, "Debug messages enabled!\n");
}
else if (message.startsWith("-dbg")) {
else if (message == "-dbg") {
socket->setProperty("ReceiveDbgMsg", false);
sendMessage(socket, "Debug messages disabled!\n");
}
else if (message.startsWith("+log")) {
else if (message == "+log") {
socket->setProperty("ReceiveLog", true);
debugOutput(socket, "Log output enabled!");
}
else if (message.startsWith("-log")) {
else if (message == "-log") {
socket->setProperty("ReceiveLog", false);
debugOutput(socket, "Log output disabled!");
}
else if (message.startsWith("+reg")) {
else if (message == "+reg") {
if (Q_LIKELY(serverSettings->canRegister)) {
QByteArray authUuid = QUuid::createUuid().toByteArray(QUuid::Id128);
QByteArray authUuid = QUuid::createUuid().toByteArray(QUuid::Id128) +
QUuid::createUuid().toByteArray(QUuid::Id128);
authUuid = QByteArray::fromHex(authUuid).toBase64(QByteArray::OmitTrailingEquals);
emit tokenRegistered(QString::fromUtf8(authUuid));
sendMessage(socket, "Token: " + authUuid + '\n');
@ -128,7 +129,7 @@ bool SMSubServer::messageReceived(QObject *socket, const QByteArray &message)
sendMessage(socket, "Permission denied!\n");
}
}
else if (message.startsWith("status")) {
else if (message == "status") {
if (status) {
sendMessage(socket, QString("Status: on\nLast Start: %1\nLast Stop: %2\n").arg(QString::number(startTime), QString::number(stopTime)).toUtf8());
}
@ -136,31 +137,31 @@ bool SMSubServer::messageReceived(QObject *socket, const QByteArray &message)
sendMessage(socket, QString("Status: off\nLast Start: %1\nLast Stop: %2\n").arg(QString::number(startTime), QString::number(stopTime)).toUtf8());
}
}
else if (message.startsWith("start")) {
else if (message == "start") {
emit startRequested();
debugOutput(socket, "Starting server!");
}
else if (message.startsWith("stop")) {
else if (message == "stop") {
emit stopRequested();
debugOutput(socket, "Stopping server!");
}
else if (message.startsWith("kill")) {
else if (message == "kill") {
emit killRequested();
debugOutput(socket, "Killing server!");
}
else if (message.startsWith("quit")) {
else if (message == "quit") {
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
debugOutput(socket, "Qutting smsub!");
}
else if (message.startsWith("wl")) {
else if (message.startsWith("wl ")) {
const QByteArray writeData = message.mid(3);
emit inputWritten(writeData + '\n');
debugOutput(socket, "Write line \"" + writeData + "\"!");
debugOutput(socket, "Write line: " + writeData);
}
else if (message.startsWith("w")) {
else if (message.startsWith("w ")) {
const QByteArray writeData = message.mid(2);
emit inputWritten(writeData);
debugOutput(socket, "Write \"" + writeData + "\"!");
debugOutput(socket, "Write: " + writeData);
}
}
else {

View file

@ -134,7 +134,7 @@ int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
a.setApplicationName("Server Manager Subprocess");
a.setApplicationVersion("0.8");
a.setApplicationVersion("0.9");
#ifdef Q_OS_UNIX
catchUnixSignals({SIGINT, SIGHUP, SIGQUIT, SIGTERM});
@ -142,9 +142,10 @@ int main(int argc, char *argv[])
bool rportSet = false;
bool autoStart = true;
bool buffReads = false;
bool keepAlive = false;
bool timeoutSet = false;
int termTimeout = 60000;
size_t termTimeout = 60000;
quint16 rport;
QString socket;
QString rsocket;
@ -154,6 +155,7 @@ int main(int argc, char *argv[])
const QByteArray envEnvironmentMode = qgetenv("SMSUB_ENVIRONMENT_MODE");
const QByteArray envAutoStart = qgetenv("SMSUB_AUTOSTART");
const QByteArray envBuffReads = qgetenv("SMSUB_BUFFERED_READS");
const QByteArray envKeepAlive = qgetenv("SMSUB_KEEPALIVE");
const QByteArray envManifest = qgetenv("SMSUB_JSON");
const QByteArray envExecutable = qgetenv("SMSUB_EXEC");
@ -212,6 +214,12 @@ int main(int argc, char *argv[])
}
}
if (!envBuffReads.isEmpty()) {
if (envBuffReads == "1" || envBuffReads.toLower() == "true" || envBuffReads.toLower() == "yes") {
buffReads = true;
}
}
if (!envKeepAlive.isEmpty()) {
if (envKeepAlive == "1" || envKeepAlive.toLower() == "true" || envKeepAlive.toLower() == "yes") {
keepAlive = true;
@ -285,6 +293,12 @@ int main(int argc, char *argv[])
#endif
commandLineParser.addOption(subprocessRemoteSocket);
QCommandLineOption processAutoStart("autostart", "SMSub autostart mode setting.", "autostart");
commandLineParser.addOption(processAutoStart);
QCommandLineOption processKeepAlive("keepalive", "SMSub keepalive mode setting.", "keepalive");
commandLineParser.addOption(processKeepAlive);
QCommandLineOption processTimeout("timeout", "SMSub termination timeout.", "timeout");
commandLineParser.addOption(processTimeout);
@ -302,7 +316,7 @@ int main(int argc, char *argv[])
!envManifest.isEmpty() && !envArguments.isEmpty() ||
commandLineParser.isSet(processManifest) && !envArguments.isEmpty() ||
!envManifest.isEmpty() && commandLineParser.isSet(processArguments)) {
QTextStream(stderr) << "You can't define a Process arguments and a JSON process manifest at the same time!" << smsub_endl;
QTextStream(stderr) << "You can't define Process arguments and a JSON process manifest at the same time!" << smsub_endl;
return 1;
}
@ -320,7 +334,7 @@ int main(int argc, char *argv[])
if (commandLineParser.isSet(processTimeout)) {
bool ok;
const int _termTimeout = commandLineParser.value(processTimeout).toInt(&ok);
const int _termTimeout = commandLineParser.value(processTimeout).toInt(&ok, 10);
if (ok) {
termTimeout = _termTimeout;
timeoutSet = true;
@ -332,7 +346,7 @@ int main(int argc, char *argv[])
}
else if (!envTimeout.isEmpty()) {
bool ok;
const int _termTimeout = envTimeout.toInt(&ok);
const int _termTimeout = envTimeout.toInt(&ok, 10);
if (ok) {
termTimeout = _termTimeout;
timeoutSet = true;
@ -350,13 +364,31 @@ int main(int argc, char *argv[])
executable = QString::fromUtf8(envExecutable);
}
if (!envAutoStart.isEmpty()) {
if (commandLineParser.isSet(processAutoStart)) {
const QString claAutoStart = commandLineParser.value(processAutoStart);
if (claAutoStart == "0" || claAutoStart.toLower() == "false" || claAutoStart.toLower() == "no") {
autoStart = false;
}
}
else if (!envAutoStart.isEmpty()) {
if (envAutoStart == "0" || envAutoStart.toLower() == "false" || envAutoStart.toLower() == "no") {
autoStart = false;
}
}
if (!envKeepAlive.isEmpty()) {
if (!envBuffReads.isEmpty()) {
if (envBuffReads == "1" || envBuffReads.toLower() == "true" || envBuffReads.toLower() == "yes") {
buffReads = true;
}
}
if (commandLineParser.isSet(processKeepAlive)) {
const QString claKeepAlive = commandLineParser.value(processKeepAlive);
if (claKeepAlive != "0" || claKeepAlive.toLower() != "false" || claKeepAlive.toLower() != "no") {
keepAlive = true;
}
}
else if (!envKeepAlive.isEmpty()) {
if (envKeepAlive == "1" || envKeepAlive.toLower() == "true" || envKeepAlive.toLower() == "yes") {
keepAlive = true;
}
@ -534,7 +566,7 @@ int main(int argc, char *argv[])
return 1;
}
SMSubProcess subProcess(executable, argumentList, workingDirectory, termTimeout, keepAlive);
SMSubProcess subProcess(executable, argumentList, workingDirectory, termTimeout, buffReads, keepAlive);
SMSubServerSettings remoteSettings;
remoteSettings.canRegister = false;