From 7a143c25055d97531dacb71f267a50273813055b Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Thu, 20 Jan 2022 14:43:54 +0100 Subject: [PATCH] Added sources for qt websocket tester --- .gitignore | 103 ++++++++++++++++++------------- README.md | 14 +++++ main.cpp | 13 ++++ mainwindow.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++ mainwindow.h | 33 ++++++++++ mainwindow.ui | 70 +++++++++++++++++++++ qtwebsockettester.pro | 15 +++++ screenshot.png | Bin 0 -> 32781 bytes 8 files changed, 345 insertions(+), 41 deletions(-) create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui create mode 100644 qtwebsockettester.pro create mode 100644 screenshot.png diff --git a/.gitignore b/.gitignore index f147edf..fab7372 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,73 @@ -# C++ objects and libs -*.slo -*.lo -*.o +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave *.a -*.la -*.lai +*.core +*.moc +*.o +*.obj +*.orig +*.rej *.so *.so.* -*.dll -*.dylib - -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc /.qmake.cache /.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* -*.moc -moc_*.cpp -moc_*.h -qrc_*.cpp -ui_*.h -*.qmlc -*.jsc -Makefile* -*build-* -*.qm -*.prl -# Qt unit tests -target_wrapper.* +# qtcreator generated files +*.pro.user* -# QtCreator -*.autosave +# xemacs temporary files +*.flc -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* +# Vim temporary files +.*.swp -# QtCreator CMake -CMakeLists.txt.user* +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* -# QtCreator 4.8< compilation database -compile_commands.json +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe -# QtCreator local machine specific files for imported projects -*creator.user* diff --git a/README.md b/README.md index 8005ede..68d87e5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # qtwebsockettester A simple graphical tool to test websocket connections + +![Screenshot](/screenshot.png) + +## Build and Run +``` +git clone git@github.com:0xFEEDC0DE64/qtwebsockettester.git +cd qtwebsockettester +mkdir build +cd build +qmake .. +make +./qtwebsockettester +``` + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..79abbe6 --- /dev/null +++ b/main.cpp @@ -0,0 +1,13 @@ +#include + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app{argc, argv}; + + MainWindow mainWindow; + mainWindow.show(); + + return app.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..65b5179 --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,138 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include + +// utilities +namespace { +template +auto qtEnumToString(const QEnum value) +{ + return QMetaEnum::fromType().valueToKey(value); +} +} // namespace + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow{parent}, + m_ui{std::make_unique()}, + m_webSocket{QString{}, QWebSocketProtocol::VersionLatest, this} +{ + m_ui->setupUi(this); + + connect(m_ui->lineEditUrl, &QLineEdit::returnPressed, this, &MainWindow::connectClicked); + connect(m_ui->pushButtonConnect, &QAbstractButton::clicked, this, &MainWindow::connectClicked); + + connect(m_ui->lineEditSend, &QLineEdit::returnPressed, this, &MainWindow::sendClicked); + connect(m_ui->pushButtonSend, &QAbstractButton::clicked, this, &MainWindow::sendClicked); + + connect(&m_webSocket, &QWebSocket::connected, this, &MainWindow::connected); + connect(&m_webSocket, &QWebSocket::disconnected, this, &MainWindow::disconnected); + connect(&m_webSocket, &QWebSocket::stateChanged, this, &MainWindow::stateChanged); + connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &MainWindow::textMessageReceived); + connect(&m_webSocket, &QWebSocket::binaryMessageReceived, this, &MainWindow::binaryMessageReceived); + connect(&m_webSocket, qOverload(&QWebSocket::error), this, &MainWindow::error); + connect(&m_webSocket, &QWebSocket::pong, this, &MainWindow::pong); + + stateChanged(m_webSocket.state()); +} + +MainWindow::~MainWindow() = default; + +void MainWindow::connectClicked() +{ + if (m_webSocket.state() == QAbstractSocket::UnconnectedState) + { + const auto url = QUrl::fromUserInput(m_ui->lineEditUrl->text()); + if (url.isEmpty()) + { + QMessageBox::warning(this, tr("Invalid url entered!"), tr("Invalid url entered!")); + return; + } + + if (url.scheme().toLower() != "ws" && + url.scheme().toLower() != "wss") + { + QMessageBox::warning(this, tr("Invalid url entered!"), tr("Only urls starting with ws:// or wss:// are allowed!")); + return; + } + + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") + .arg(QTime::currentTime().toString()) + .arg(tr("Connecting to %0").arg(url.toString()))); + + m_webSocket.open(url); + } + else + m_webSocket.close(); +} + +void MainWindow::sendClicked() +{ + if (m_webSocket.state() != QAbstractSocket::ConnectedState) + { + QMessageBox::warning(this, tr("WebSocket not connected!"), tr("WebSocket not connected!")); + return; + } + + const auto msg = m_ui->lineEditSend->text(); + m_webSocket.sendTextMessage(msg); + m_ui->lineEditSend->clear(); + + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %2: %3
") + .arg(QTime::currentTime().toString()) + .arg("red") + .arg(tr("SEND")) + .arg(msg)); +} + +void MainWindow::connected() +{ + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") + .arg(QTime::currentTime().toString()) + .arg(tr("Connected"))); +} + +void MainWindow::disconnected() +{ + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") + .arg(QTime::currentTime().toString()) + .arg(tr("Disconnected"))); +} + +void MainWindow::stateChanged(QAbstractSocket::SocketState state) +{ + m_ui->lineEditUrl->setEnabled(state == QAbstractSocket::UnconnectedState); + m_ui->pushButtonConnect->setText(state == QAbstractSocket::UnconnectedState ? tr("Connect") : tr("Disconnect")); + m_ui->labelStatus->setText(qtEnumToString(state)); + m_ui->lineEditSend->setEnabled(state == QAbstractSocket::ConnectedState); + m_ui->pushButtonSend->setEnabled(state == QAbstractSocket::ConnectedState); +} + +void MainWindow::textMessageReceived(const QString &message) +{ + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %2: %3
") + .arg(QTime::currentTime().toString()) + .arg("green") + .arg(tr("RECV")) + .arg(message)); +} + +void MainWindow::binaryMessageReceived(const QByteArray &message) +{ + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %2: %3
") + .arg(QTime::currentTime().toString()) + .arg("blue") + .arg(tr("RECV")) + .arg(tr("<BINARY>"))); +} + +void MainWindow::error(QAbstractSocket::SocketError error) +{ + QMessageBox::warning(this, tr("WebSocket error occured!"), tr("WebSocket error occured!") + "\n\n" + qtEnumToString(error)); +} + +void MainWindow::pong(quint64 elapsedTime, const QByteArray &payload) +{ + qDebug() << "pong" << elapsedTime; +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..dc4da40 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +#include + +namespace Ui { class MainWindow; } + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private slots: + void connectClicked(); + void sendClicked(); + + void connected(); + void disconnected(); + void stateChanged(QAbstractSocket::SocketState state); + void textMessageReceived(const QString &message); + void binaryMessageReceived(const QByteArray &message); + void error(QAbstractSocket::SocketError error); + void pong(quint64 elapsedTime, const QByteArray &payload); + +private: + const std::unique_ptr m_ui; + QWebSocket m_webSocket; +}; diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..0d7fbc8 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,70 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + WebSocket Tester + + + + + + + + + ws://localhost:1234/path/to/ws + + + + + + + Connect + + + + + + + TextLabel + + + + + + + + + + + + + + Send + + + + + + + + + true + + + + + + + + + + diff --git a/qtwebsockettester.pro b/qtwebsockettester.pro new file mode 100644 index 0000000..01827d7 --- /dev/null +++ b/qtwebsockettester.pro @@ -0,0 +1,15 @@ +QT = core gui widgets network websockets + +CONFIG += c++latest + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + main.cpp \ + mainwindow.cpp + +FORMS += \ + mainwindow.ui + +HEADERS += \ + mainwindow.h diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..58838f9d0bf1893ae496fa96f9c99b25d0ca33e5 GIT binary patch literal 32781 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 literal 0 HcmV?d00001