Added sources for qt websocket tester

This commit is contained in:
2022-01-20 14:43:54 +01:00
parent d3d891b0df
commit 7a143c2505
8 changed files with 345 additions and 41 deletions

103
.gitignore vendored
View File

@ -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*

View File

@ -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
```

13
main.cpp Normal file
View File

@ -0,0 +1,13 @@
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app{argc, argv};
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}

138
mainwindow.cpp Normal file
View File

@ -0,0 +1,138 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QMetaEnum>
// utilities
namespace {
template<typename QEnum>
auto qtEnumToString(const QEnum value)
{
return QMetaEnum::fromType<QEnum>().valueToKey(value);
}
} // namespace
MainWindow::MainWindow(QWidget *parent) :
QMainWindow{parent},
m_ui{std::make_unique<Ui::MainWindow>()},
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<QAbstractSocket::SocketError>(&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("<b>%0</b> <i>%1</i><br/>")
.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("<b>%0</b> <span style=\"color: %1;\">%2</span>: %3<br/>")
.arg(QTime::currentTime().toString())
.arg("red")
.arg(tr("SEND"))
.arg(msg));
}
void MainWindow::connected()
{
m_ui->plainTextEdit->appendHtml(QStringLiteral("<b>%0</b> <i>%1</i><br/>")
.arg(QTime::currentTime().toString())
.arg(tr("Connected")));
}
void MainWindow::disconnected()
{
m_ui->plainTextEdit->appendHtml(QStringLiteral("<b>%0</b> <i>%1</i><br/>")
.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("<b>%0</b> <span style=\"color: %1;\">%2</span>: %3<br/>")
.arg(QTime::currentTime().toString())
.arg("green")
.arg(tr("RECV"))
.arg(message));
}
void MainWindow::binaryMessageReceived(const QByteArray &message)
{
m_ui->plainTextEdit->appendHtml(QStringLiteral("<b>%0</b> <span style=\"color: %1;\">%2</span>: %3<br/>")
.arg(QTime::currentTime().toString())
.arg("blue")
.arg(tr("RECV"))
.arg(tr("&lt;BINARY&gt;")));
}
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;
}

33
mainwindow.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include <QMainWindow>
#include <QWebSocket>
#include <memory>
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<Ui::MainWindow> m_ui;
QWebSocket m_webSocket;
};

70
mainwindow.ui Normal file
View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>WebSocket Tester</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEditUrl">
<property name="text">
<string>ws://localhost:1234/path/to/ws</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonConnect">
<property name="text">
<string>Connect</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelStatus">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="lineEditSend"/>
</item>
<item>
<widget class="QPushButton" name="pushButtonSend">
<property name="text">
<string>Send</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

15
qtwebsockettester.pro Normal file
View File

@ -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

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB