Add Dockerfile, make redis feature optional, add listening address cmdline parameter
This commit is contained in:
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
build/
|
||||||
|
*.user*
|
||||||
|
Dockerfile
|
||||||
|
.git/
|
||||||
|
.gitignore
|
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
FROM registry.brunner.ninja/library/ubuntu:devel AS build
|
||||||
|
|
||||||
|
RUN apt update \
|
||||||
|
&& DEBIAN_FRONTEND=noninteractive apt install libqt6core6 libqt6httpserver6 libqt6websockets6 -y \
|
||||||
|
&& rm /var/lib/apt/lists/* /var/log/* -Rf
|
||||||
|
|
||||||
|
RUN apt update \
|
||||||
|
&& DEBIAN_FRONTEND=noninteractive apt install qmake6 g++ make qt6-base-dev qt6-websockets-dev qt6-httpserver-dev -y \
|
||||||
|
&& rm /var/lib/apt/lists/* /var/log/* -Rf
|
||||||
|
|
||||||
|
COPY ./ /less_shitty_proxyjs
|
||||||
|
|
||||||
|
RUN mkdir -pv /build \
|
||||||
|
&& cd /build \
|
||||||
|
&& qmake6 /less_shitty_proxyjs \
|
||||||
|
&& make -j4 \
|
||||||
|
&& ls -lah
|
||||||
|
|
||||||
|
FROM registry.brunner.ninja/library/ubuntu:devel AS runtime
|
||||||
|
|
||||||
|
RUN apt update \
|
||||||
|
&& DEBIAN_FRONTEND=noninteractive apt install libqt6core6 libqt6httpserver6 libqt6websockets6 -y \
|
||||||
|
&& rm /var/lib/apt/lists/* /var/log/* -Rf
|
||||||
|
|
||||||
|
COPY --from=build /build/less_shitty_proxyjs /less_shitty_proxyjs
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/less_shitty_proxyjs", "Any", "1234" ]
|
||||||
|
|
||||||
|
EXPOSE 1234
|
@@ -81,7 +81,11 @@ void Client::socketDisconnected()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serialClients.empty())
|
if (serialClients.empty())
|
||||||
|
{
|
||||||
|
#ifdef FEATURE_REDIS
|
||||||
m_server.destroyTraefikRoute(m_serial);
|
m_server.destroyTraefikRoute(m_serial);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else for (auto &ptr : serialClients)
|
else for (auto &ptr : serialClients)
|
||||||
ptr->sendTextMessage(QString{"A client disconnected, number of remaining connected clients: %0"}.arg(serialClients.size()));
|
ptr->sendTextMessage(QString{"A client disconnected, number of remaining connected clients: %0"}.arg(serialClients.size()));
|
||||||
|
|
||||||
|
@@ -4,11 +4,14 @@ CONFIG += c++latest cmdline
|
|||||||
|
|
||||||
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000
|
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
client.h \
|
||||||
|
webserver.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
client.cpp \
|
client.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
redisqtadapter.cpp \
|
webserver.cpp
|
||||||
webserver.cpp
|
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources.qrc
|
resources.qrc
|
||||||
@@ -19,10 +22,9 @@ OTHER_FILES += \
|
|||||||
script.js \
|
script.js \
|
||||||
style.css
|
style.css
|
||||||
|
|
||||||
HEADERS += \
|
redis {
|
||||||
client.h \
|
HEADERS += redisqtadapter.h
|
||||||
redisqtadapter.h \
|
SOURCES += redisqtadapter.cpp
|
||||||
webserver.h
|
LIBS += -L/usr/lib -lhiredis
|
||||||
|
DEFINES += FEATURE_REDIS
|
||||||
LIBS += \
|
}
|
||||||
-L/usr/lib -lhiredis
|
|
||||||
|
29
main.cpp
29
main.cpp
@@ -23,21 +23,36 @@ int main(int argc, char *argv[])
|
|||||||
QCoreApplication::setApplicationName("less_shitty_proxyjs");
|
QCoreApplication::setApplicationName("less_shitty_proxyjs");
|
||||||
QCoreApplication::setApplicationVersion("1.0");
|
QCoreApplication::setApplicationVersion("1.0");
|
||||||
|
|
||||||
QString identity = "test";
|
QHostAddress listenAddress = QHostAddress::Any;
|
||||||
uint16_t port = 8000;
|
uint16_t port = 8000;
|
||||||
|
QString identity = "test";
|
||||||
|
|
||||||
{
|
{
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription("Test helper");
|
parser.setApplicationDescription("Test helper");
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.addVersionOption();
|
parser.addVersionOption();
|
||||||
parser.addPositionalArgument("identiy", QCoreApplication::translate("main", "The name of this service instance"));
|
parser.addPositionalArgument("listenAddr", QCoreApplication::translate("main", "The address to listen on (Can be \"Any\" \"Localhost\" or any valid ip address)."));
|
||||||
parser.addPositionalArgument("port", QCoreApplication::translate("main", "The port to listen on (will only listen on localhost)."));
|
parser.addPositionalArgument("port", QCoreApplication::translate("main", "The port to listen on (will only listen on localhost)."));
|
||||||
|
parser.addPositionalArgument("identiy", QCoreApplication::translate("main", "The name of this service instance"));
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
|
|
||||||
const auto &args = parser.positionalArguments();
|
const auto &args = parser.positionalArguments();
|
||||||
if (args.size() > 0)
|
if (args.size() > 0)
|
||||||
identity = args.first();
|
{
|
||||||
|
if (const auto &str = args.first(); str == "Any")
|
||||||
|
listenAddress = QHostAddress::Any;
|
||||||
|
else if (str == "AnyIPv4")
|
||||||
|
listenAddress = QHostAddress::AnyIPv4;
|
||||||
|
else if (str == "AnyIPv6")
|
||||||
|
listenAddress = QHostAddress::AnyIPv6;
|
||||||
|
else if (str == "LocalHost")
|
||||||
|
listenAddress = QHostAddress::LocalHost;
|
||||||
|
else if (str == "LocalHostIPv6")
|
||||||
|
listenAddress = QHostAddress::LocalHostIPv6;
|
||||||
|
else
|
||||||
|
listenAddress = QHostAddress{str};
|
||||||
|
}
|
||||||
if (args.size() > 1)
|
if (args.size() > 1)
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
@@ -48,6 +63,8 @@ int main(int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (args.size() > 2)
|
||||||
|
identity = args.at(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
qSetMessagePattern(QString{"%{time dd.MM.yyyy HH:mm:ss.zzz} %0 "
|
qSetMessagePattern(QString{"%{time dd.MM.yyyy HH:mm:ss.zzz} %0 "
|
||||||
@@ -64,9 +81,9 @@ int main(int argc, char *argv[])
|
|||||||
WebServer server{identity, QString{"http://localhost:%0"}.arg(port)};
|
WebServer server{identity, QString{"http://localhost:%0"}.arg(port)};
|
||||||
|
|
||||||
QTcpServer tcpServer;
|
QTcpServer tcpServer;
|
||||||
if (!tcpServer.listen(QHostAddress::LocalHost, port))
|
if (!tcpServer.listen(listenAddress, port))
|
||||||
{
|
{
|
||||||
qCritical("failed to start listening on port %hu: %s", port, qPrintable(tcpServer.errorString()));
|
qCritical("failed to start listening on addr %s port %hu: %s", qPrintable(listenAddress.toString()), port, qPrintable(tcpServer.errorString()));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +93,7 @@ int main(int argc, char *argv[])
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "server started";
|
qDebug() << "server started on" << listenAddress << "port" << port;
|
||||||
|
|
||||||
auto result = app.exec();
|
auto result = app.exec();
|
||||||
qDebug() << "bey bey!";
|
qDebug() << "bey bey!";
|
||||||
|
@@ -14,6 +14,7 @@ WebServer::WebServer(const QString &identity, const QString &url, QObject *paren
|
|||||||
QObject{parent},
|
QObject{parent},
|
||||||
m_identity{identity}
|
m_identity{identity}
|
||||||
{
|
{
|
||||||
|
#ifdef FEATURE_REDIS
|
||||||
m_redis = redisAsyncConnect("localhost", 6379);
|
m_redis = redisAsyncConnect("localhost", 6379);
|
||||||
|
|
||||||
if (m_redis->err)
|
if (m_redis->err)
|
||||||
@@ -25,6 +26,9 @@ WebServer::WebServer(const QString &identity, const QString &url, QObject *paren
|
|||||||
QString{"traefik/http/services/proxyjs_%0/loadbalancer/servers/0/url"}.arg(m_identity).toUtf8().constData(),
|
QString{"traefik/http/services/proxyjs_%0/loadbalancer/servers/0/url"}.arg(m_identity).toUtf8().constData(),
|
||||||
url.toUtf8().constData());
|
url.toUtf8().constData());
|
||||||
|
|
||||||
|
qDebug() << "redis connected";
|
||||||
|
#endif
|
||||||
|
|
||||||
m_server.route("/", [&]() {
|
m_server.route("/", [&]() {
|
||||||
return serveHtmlWithPlaceholders(":/lspjs/index.html", {
|
return serveHtmlWithPlaceholders(":/lspjs/index.html", {
|
||||||
{"identity", identity}
|
{"identity", identity}
|
||||||
@@ -65,6 +69,7 @@ void WebServer::newWebSocketConnection()
|
|||||||
newWebSocketConnection(std::move(socket));
|
newWebSocketConnection(std::move(socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEATURE_REDIS
|
||||||
void WebServer::createTraefikRoute(const QString &serial)
|
void WebServer::createTraefikRoute(const QString &serial)
|
||||||
{
|
{
|
||||||
qDebug() << "create traefik route for" << serial << "to" << m_identity;
|
qDebug() << "create traefik route for" << serial << "to" << m_identity;
|
||||||
@@ -109,6 +114,7 @@ void WebServer::destroyTraefikRoute(const QString &serial)
|
|||||||
redisAsyncCommand(m_redis, NULL, NULL, "DEL %s",
|
redisAsyncCommand(m_redis, NULL, NULL, "DEL %s",
|
||||||
QString{"traefik/http/routers/proxyjs_%0/priority"}.arg(serial).toUtf8().constData());
|
QString{"traefik/http/routers/proxyjs_%0/priority"}.arg(serial).toUtf8().constData());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QHttpServerWebSocketUpgradeResponse WebServer::verifySocketUpgrade(const QHttpServerRequest &request)
|
QHttpServerWebSocketUpgradeResponse WebServer::verifySocketUpgrade(const QHttpServerRequest &request)
|
||||||
{
|
{
|
||||||
@@ -131,7 +137,11 @@ void WebServer::newWebSocketConnection(std::unique_ptr<QWebSocket> &&socket)
|
|||||||
|
|
||||||
auto &set = m_clients[serial];
|
auto &set = m_clients[serial];
|
||||||
if (set.empty())
|
if (set.empty())
|
||||||
|
{
|
||||||
|
#ifdef FEATURE_REDIS
|
||||||
createTraefikRoute(serial);
|
createTraefikRoute(serial);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
set.emplace(std::make_unique<Client>(*this, std::move(socket), serial, set));
|
set.emplace(std::make_unique<Client>(*this, std::move(socket), serial, set));
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,10 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef FEATURE_REDIS
|
||||||
#include <hiredis/async.h>
|
#include <hiredis/async.h>
|
||||||
#include "redisqtadapter.h"
|
#include "redisqtadapter.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class QWebSocket;
|
class QWebSocket;
|
||||||
class Client;
|
class Client;
|
||||||
@@ -28,8 +30,10 @@ private slots:
|
|||||||
void newWebSocketConnection();
|
void newWebSocketConnection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifdef FEATURE_REDIS
|
||||||
void createTraefikRoute(const QString &serial);
|
void createTraefikRoute(const QString &serial);
|
||||||
void destroyTraefikRoute(const QString &serial);
|
void destroyTraefikRoute(const QString &serial);
|
||||||
|
#endif
|
||||||
|
|
||||||
QHttpServerWebSocketUpgradeResponse verifySocketUpgrade(const QHttpServerRequest &request);
|
QHttpServerWebSocketUpgradeResponse verifySocketUpgrade(const QHttpServerRequest &request);
|
||||||
void newWebSocketConnection(std::unique_ptr<QWebSocket> &&socket);
|
void newWebSocketConnection(std::unique_ptr<QWebSocket> &&socket);
|
||||||
@@ -40,6 +44,8 @@ private:
|
|||||||
|
|
||||||
std::unordered_map<QString, std::set<std::unique_ptr<Client>>> m_clients;
|
std::unordered_map<QString, std::set<std::unique_ptr<Client>>> m_clients;
|
||||||
|
|
||||||
|
#ifdef FEATURE_REDIS
|
||||||
redisAsyncContext *m_redis;
|
redisAsyncContext *m_redis;
|
||||||
RedisQtAdapter m_redisAdapter;
|
RedisQtAdapter m_redisAdapter;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user