Added sources for qt websocket tester
This commit is contained in:
103
.gitignore
vendored
103
.gitignore
vendored
@ -1,52 +1,73 @@
|
|||||||
# C++ objects and libs
|
# This file is used to ignore files which are generated
|
||||||
*.slo
|
# ----------------------------------------------------------------------------
|
||||||
*.lo
|
|
||||||
*.o
|
*~
|
||||||
|
*.autosave
|
||||||
*.a
|
*.a
|
||||||
*.la
|
*.core
|
||||||
*.lai
|
*.moc
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
*.so.*
|
||||||
*.dll
|
*_pch.h.cpp
|
||||||
*.dylib
|
*_resource.rc
|
||||||
|
*.qm
|
||||||
# Qt-es
|
.#*
|
||||||
object_script.*.Release
|
*.*#
|
||||||
object_script.*.Debug
|
core
|
||||||
*_plugin_import.cpp
|
!core/
|
||||||
|
tags
|
||||||
|
.DS_Store
|
||||||
|
.directory
|
||||||
|
*.debug
|
||||||
|
Makefile*
|
||||||
|
*.prl
|
||||||
|
*.app
|
||||||
|
moc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
Thumbs.db
|
||||||
|
*.res
|
||||||
|
*.rc
|
||||||
/.qmake.cache
|
/.qmake.cache
|
||||||
/.qmake.stash
|
/.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
|
# qtcreator generated files
|
||||||
target_wrapper.*
|
*.pro.user*
|
||||||
|
|
||||||
# QtCreator
|
# xemacs temporary files
|
||||||
*.autosave
|
*.flc
|
||||||
|
|
||||||
# QtCreator Qml
|
# Vim temporary files
|
||||||
*.qmlproject.user
|
.*.swp
|
||||||
*.qmlproject.user.*
|
|
||||||
|
|
||||||
# QtCreator CMake
|
# Visual Studio generated files
|
||||||
CMakeLists.txt.user*
|
*.ib_pdb_index
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.vcproj
|
||||||
|
*vcproj.*.*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.vcxproj
|
||||||
|
*vcxproj.*
|
||||||
|
|
||||||
# QtCreator 4.8< compilation database
|
# MinGW generated files
|
||||||
compile_commands.json
|
*.Debug
|
||||||
|
*.Release
|
||||||
|
|
||||||
|
# Python byte code
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Binaries
|
||||||
|
# --------
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
|
||||||
# QtCreator local machine specific files for imported projects
|
|
||||||
*creator.user*
|
|
||||||
|
14
README.md
14
README.md
@ -1,2 +1,16 @@
|
|||||||
# qtwebsockettester
|
# qtwebsockettester
|
||||||
A simple graphical tool to test websocket connections
|
A simple graphical tool to test websocket connections
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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
13
main.cpp
Normal 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
138
mainwindow.cpp
Normal 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("<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;
|
||||||
|
}
|
33
mainwindow.h
Normal file
33
mainwindow.h
Normal 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
70
mainwindow.ui
Normal 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
15
qtwebsockettester.pro
Normal 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
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Reference in New Issue
Block a user