Skip to content

Commit

Permalink
Allow control of all visualisation server ports
Browse files Browse the repository at this point in the history
  • Loading branch information
cyderize committed Nov 26, 2023
1 parent 8406765 commit e6dc9a6
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 55 deletions.
18 changes: 10 additions & 8 deletions MiniZincIDE/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3085,17 +3085,19 @@ void MainWindow::startVisualisation(const QString& model, const QStringList& dat
QSettings settings;
settings.beginGroup("ide");
bool reuseVis = settings.value("reuseVis", false).toBool();
int port = settings.value("visPort", 3000).toInt();
int httpPort = settings.value("visPort", 3000).toInt();
int wsPort = settings.value("visWsPort", 3100).toInt();
bool printUrl = settings.value("printVisUrl", false).toBool();
settings.endGroup();

if (server == nullptr || server->desiredPort() != port) {
try {
server = new Server(port, this);
} catch (ServerError& e) {
QMessageBox::warning(this, "MiniZinc IDE", e.message(), QMessageBox::Ok);
return;
}
if (server == nullptr) {
server = new Server(this);
}
try {
server->listen(httpPort, wsPort);
} catch (ServerError& e) {
QMessageBox::warning(this, "MiniZinc IDE", e.message(), QMessageBox::Ok);
return;
}

QFileInfo modelFileInfo(model);
Expand Down
2 changes: 2 additions & 0 deletions MiniZincIDE/preferencesdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ PreferencesDialog::PreferencesDialog(bool addNewSolver, QWidget *parent) :
}
ui->reuseVis_checkBox->setChecked(settings.value("reuseVis", false).toBool());
ui->visPort_spinBox->setValue(settings.value("visPort", 3000).toInt());
ui->visWsPort_spinBox->setValue(settings.value("visWsPort", 3100).toInt());
ui->visUrl_checkBox->setChecked(settings.value("printVisUrl", false).toBool());
ui->printCommand_checkBox->setChecked(settings.value("printCommand", false).toBool());
ui->indentSize_spinBox->setValue(settings.value("indentSize", 2).toInt());
Expand Down Expand Up @@ -919,6 +920,7 @@ void PreferencesDialog::on_PreferencesDialog_accepted()
settings.setValue("printCommand", ui->printCommand_checkBox->isChecked());
settings.setValue("reuseVis", ui->reuseVis_checkBox->isChecked());
settings.setValue("visPort", ui->visPort_spinBox->value());
settings.setValue("visWsPort", ui->visWsPort_spinBox->value());
settings.setValue("printVisUrl", ui->visUrl_checkBox->isChecked());
settings.setValue("theme", ui->theme_comboBox->currentIndex());
settings.setValue("indentTabs", ui->indentTabs_radioButton->isChecked());
Expand Down
74 changes: 46 additions & 28 deletions MiniZincIDE/preferencesdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -794,34 +794,52 @@
<property name="title">
<string>Visualisation</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="reuseVis_checkBox">
<property name="text">
<string>Reuse existing visualisation window when starting a new run</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Start the visualisation server on this port (0 for auto):</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="visPort_spinBox">
<property name="maximum">
<number>65535</number>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="visUrl_checkBox">
<property name="text">
<string>Print the visualisation server URL in the output window</string>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout_16">
<item>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="reuseVis_checkBox">
<property name="text">
<string>Reuse existing visualisation window when starting a new run</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>HTTP server port (0 for auto):</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="visPort_spinBox">
<property name="maximum">
<number>65535</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>WebSocket server port (0 for auto):</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="visWsPort_spinBox">
<property name="maximum">
<number>65535</number>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="visUrl_checkBox">
<property name="text">
<string>Print the visualisation server URL in the output window</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
Expand Down
50 changes: 34 additions & 16 deletions MiniZincIDE/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,26 +178,11 @@ void VisConnector::webSocketMessageReceived(const QString& message)
}
}

Server::Server(quint16 port, QObject *parent) :
Server::Server(QObject *parent) :
QObject(parent),
http(new QTcpServer(this)),
ws(new QWebSocketServer("MiniZincIDE", QWebSocketServer::NonSecureMode, this))
{
initialPort = port;
qint16 p = port;
for (int i = 0; i < 10; i++) {
if (http->listen(QHostAddress::LocalHost, p) || p == 0) {
break;
}
p++;
}
if (!http->isListening()) {
throw ServerError("Failed to start HTTP visualisation server");
}
if (!ws->listen(QHostAddress::LocalHost)) {
throw ServerError("Failed to start WebSocket visualisation server");
}

connect(http, &QTcpServer::newConnection, this, &Server::newHttpClient);
connect(ws, &QWebSocketServer::newConnection, this, &Server::newWebSocketClient);
}
Expand All @@ -209,6 +194,39 @@ Server::~Server()
}
}

void Server::listen(quint16 httpPort, quint16 wsPort)
{
if (!http->isListening() || httpPort != initialHttpPort) {
initialHttpPort = httpPort;
qint16 p = httpPort;
http->close();
for (int i = 0; i < 10; i++) {
if (http->listen(QHostAddress::LocalHost, p) || p == 0) {
break;
}
p++;
}
if (!http->isListening()) {
throw ServerError("Failed to start HTTP visualisation server");
}
}

if (!ws->isListening() || wsPort != initialWsPort) {
initialWsPort = wsPort;
quint16 p = wsPort;
ws->close();
for (int i = 0; i < 10; i++) {
if (ws->listen(QHostAddress::LocalHost, p) || p == 0) {
break;
}
p++;
}
if (!ws->isListening()) {
throw ServerError("Failed to start WebSocket visualisation server");
}
}
}

VisConnector* Server::addConnector(const QString& label, const QStringList& roots)
{
auto* c = new VisConnector(this);
Expand Down
11 changes: 8 additions & 3 deletions MiniZincIDE/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ class Server : public QObject
{
Q_OBJECT
public:
explicit Server(quint16 port = 3000, QObject *parent = nullptr);
explicit Server(QObject *parent = nullptr);
~Server();

void listen(quint16 httpPort = 3000, quint16 wsPort = 3100);

QString address() const { return http->serverAddress().toString(); }
quint16 port() const { return http->serverPort(); }
quint16 desiredPort() const { return initialPort; }
quint16 desiredHttpPort() const { return initialHttpPort; }
quint16 desiredWsPort() const { return initialWsPort; }

VisConnector* addConnector(const QString& label, const QStringList& roots);
void clear();
Expand All @@ -78,7 +82,8 @@ private slots:
QWebSocketServer* ws;
QList<VisConnector*> connectors;
QList<QWebSocket*> clients;
quint16 initialPort;
quint16 initialHttpPort;
quint16 initialWsPort;
};

#endif // SERVER_H

0 comments on commit e6dc9a6

Please sign in to comment.