From 847393cec38fb294a737597e1925ec7d786d6c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Heredero?= Date: Wed, 29 Nov 2023 11:53:20 +0100 Subject: [PATCH] create interface --- STOMPClient.pro | 6 ++++++ app.cpp | 5 +++++ app.h | 12 ++++++++++++ interface/iStompObserver.h | 16 ++++++++++++++++ interface/iStompSubject.h | 29 +++++++++++++++++++++++++++++ main.cpp | 25 ++++++++++++++++++++++++- stomp.cpp | 16 ++++++++++++++++ stomp.h | 35 +++++++++++++++++++++++++++++++++++ stompframe.cpp | 5 +++++ 9 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 app.cpp create mode 100644 app.h create mode 100644 interface/iStompObserver.h create mode 100644 interface/iStompSubject.h create mode 100644 stomp.cpp create mode 100644 stomp.h diff --git a/STOMPClient.pro b/STOMPClient.pro index e3e96e3..804c68a 100644 --- a/STOMPClient.pro +++ b/STOMPClient.pro @@ -2,7 +2,13 @@ QT += network gui widgets CONFIG += c++14 console CONFIG -= app_bundle HEADERS += \ + app.h \ + interface/iStompObserver.h \ + interface/iStompSubject.h \ + stomp.h \ stompframe.h SOURCES += \ + app.cpp \ main.cpp \ + stomp.cpp \ stompframe.cpp diff --git a/app.cpp b/app.cpp new file mode 100644 index 0000000..5f73395 --- /dev/null +++ b/app.cpp @@ -0,0 +1,5 @@ +#include "app.h" + +App::App() { + +} diff --git a/app.h b/app.h new file mode 100644 index 0000000..4254ebd --- /dev/null +++ b/app.h @@ -0,0 +1,12 @@ +#ifndef APP_H +#define APP_H + +#include +#include "interface/iStompObserver.h" + +class App : public QObject, public interface::iStompObserver { +public: + App(); +}; + +#endif // APP_H diff --git a/interface/iStompObserver.h b/interface/iStompObserver.h new file mode 100644 index 0000000..e81ce3c --- /dev/null +++ b/interface/iStompObserver.h @@ -0,0 +1,16 @@ +#ifndef ISTOMPOBSERVER_H +#define ISTOMPOBSERVER_H + +#include + +namespace interface { +class iStompObserver { + virtual void connectConfirmation(bool success, int version); + virtual void sendConfirmation(bool success); + virtual void subscribeConfirmation(bool success); + virtual void receiveIndication(int id, QString destination, QString body); + virtual void disconnectConfirmation(); + virtual void disconnectIndication(); +}; +} +#endif // ISTOMPOBSERVER_H diff --git a/interface/iStompSubject.h b/interface/iStompSubject.h new file mode 100644 index 0000000..d9278da --- /dev/null +++ b/interface/iStompSubject.h @@ -0,0 +1,29 @@ +#ifndef ISTOMPSUBJECT_H +#define ISTOMPSUBJECT_H + +#include "iStompObserver.h" +#include + +namespace interface { +class iStompSubject { +public: + virtual bool subscribe(iStompObserver* obs); + virtual void unsubscribe(iStompObserver* obs); + + virtual void connectRequest(QString host, int port, QString vhost, QString username, QString password); + virtual void sendRequest(QString destination, QString body); + virtual void subscribeRequest(QString destination, int id); + virtual void disconnectRequest(); + +protected: + virtual void notifyConnectConfirmation(bool success, int version); + virtual void notifySendConfirmation(bool success); + virtual void notifySubscribeConfirmation(bool success); + virtual void notifyReceiveIndication(int id, QString destination, QString body); + virtual void notifyDisconnectConfirmation(); + virtual void notifyDisconnectIndication(); + +}; +} // namespace + +#endif // ISTOMPSUBJECT_H diff --git a/main.cpp b/main.cpp index bf2b52a..d351f99 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,30 @@ #include +#include + +#include "stompframe.h" int main(int argc, char *argv[]) { QApplication application(argc, argv); - + + QSslSocket socket; + socket.setPeerVerifyMode(QSslSocket::VerifyNone); + + + QObject::connect(&socket, &QSslSocket::readyRead, [&]() { + auto frame = STOMPFrame::receive(socket); + + qDebug() << "Connected:" << (frame.command() == STOMPFrame::CONNECTED) << Qt::endl + << "Version:" << frame.headers().value("version"); + }); + + socket.connectToHostEncrypted("sdi.hevs.ch", 61614); + if(!socket.waitForConnected()) return -1; + + STOMPFrame(STOMPFrame::STOMP, { + {"accept-version", "1.2"}, + {"host", "/"}, + {"login", "sdi10"}, + {"passcode", "809c02f36becb0868da98761fe3209f6"} + }).send(socket); return application.exec(); } diff --git a/stomp.cpp b/stomp.cpp new file mode 100644 index 0000000..2f947fb --- /dev/null +++ b/stomp.cpp @@ -0,0 +1,16 @@ +#include "stomp.h" + +Stomp::Stomp() { + +} + +bool Stomp::subscribe(interface::iStompObserver obs) { + for(int i = 0; i < MAX_OBSERVER; i++) { + if (observer_[i] == nullptr) { + observer_[i] = obs; + return true; + } + } + return false; + + diff --git a/stomp.h b/stomp.h new file mode 100644 index 0000000..46e4b4e --- /dev/null +++ b/stomp.h @@ -0,0 +1,35 @@ +#ifndef STOMP_H +#define STOMP_H + +#include +#include "interface/iStompSubject.h" + +#define MAX_OBSERVER 5 + +class Stomp : public QObject, public interface::iStompSubject{ +public: + Stomp(); + + + // iStompSubject interface +public: + bool subscribe(interface::iStompObserver* obs); + void unsubscribe(interface::iStompObserver* obs); + void connectRequest(QString host, int port, QString vhost, QString username, QString password); + void sendRequest(QString destination, QString body); + void subscribeRequest(QString destination, int id); + void disconnectRequest(); + +protected: + void notifyConnectConfirmation(bool success, int version); + void notifySendConfirmation(bool success); + void notifySubscribeConfirmation(bool success); + void notifyReceiveIndication(int id, QString destination, QString body); + void notifyDisconnectConfirmation(); + void notifyDisconnectIndication(); + +protected: + interface::iStompObserver* observer_[MAX_OBSERVER]; +}; + +#endif // STOMP_H diff --git a/stompframe.cpp b/stompframe.cpp index 0b40080..9e8b8d0 100644 --- a/stompframe.cpp +++ b/stompframe.cpp @@ -2,21 +2,26 @@ STOMPFrame::STOMPFrame(Command command, std::initializer_list> headers, const QByteArray& body): command_(command), body_(body) { + for (const auto& header: headers) { headers_[header.first] = header.second; } } qint64 STOMPFrame::send(QIODevice& device) { + QByteArray encoded; QTextStream out {&encoded}; out << command_ << "\n"; + for (const auto& key: headers_.keys()) { out << key << ":" << headers_[key] << "\n"; } + if (!headers_.contains("content-length")) { out << "content-length" << ":" << body_.size() << "\n"; } + out << "\n" << body_ << '\0'; out.flush(); return device.write(encoded);