Merge remote-tracking branch 'render/main' into master-new-assignement
# Conflicts: # .gitignore # main.cpp # stompframe.cpp
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +1,4 @@ | |||||||
| *.pro.user | *.pro.user | ||||||
|  | cmake-build-debug | ||||||
|  | .idea | ||||||
|  | cmake-build-debug-visual-studio | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | cmake_minimum_required(VERSION 3.22) | ||||||
|  | project(ProtocolDeveloppement) | ||||||
|  |  | ||||||
|  | set(CMAKE_CXX_STANDARD 14) | ||||||
|  |  | ||||||
|  | #set(CMAKE_PREFIX_PATH "/Qt/6.5.0/android_arm64_v8a/lib/cmake") | ||||||
|  | #set(CMAKE_PREFIX_PATH "D:/programme/Qt/6.5.0/mingw_64/lib/cmake") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | find_package(Qt6Widgets REQUIRED) | ||||||
|  | find_package(Qt6Network REQUIRED) | ||||||
|  | find_package(Qt6Gui REQUIRED) | ||||||
|  |  | ||||||
|  | add_executable(${PROJECT_NAME} | ||||||
|  |         main.cpp | ||||||
|  |         stompframe.cpp | ||||||
|  |         stomp.cpp | ||||||
|  |         app.cpp | ||||||
|  |         Vector2D.cpp | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | link_directories( ${PCL_LIBRARY_DIRS} ) | ||||||
|  |  | ||||||
|  | target_link_libraries(${PROJECT_NAME} | ||||||
|  |         Qt6::Network | ||||||
|  |         Qt6::Gui | ||||||
|  |         Qt6::Widgets | ||||||
|  | ) | ||||||
							
								
								
									
										49
									
								
								Vector2D.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								Vector2D.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | #include "Vector2D.h" | ||||||
|  |  | ||||||
|  | Vector2D::Vector2D(Point point) { | ||||||
|  |     point_.x = point.x; | ||||||
|  |     point_.y = point.y; | ||||||
|  |     lenght_ = sqrt(pow(point.x, 2) + pow(point.y, 2)); | ||||||
|  |     angle_ = atan2(point.y, point.x); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Vector2D::Vector2D(double lenght, double angle) { | ||||||
|  |     lenght_ = lenght; | ||||||
|  |     angle_ = angle; | ||||||
|  |     point_.x = lenght * cos(angle); | ||||||
|  |     point_.y = lenght * sin(angle); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Vector2D::Point Vector2D::CreatePoint(double x, double y) { | ||||||
|  |     Point p; | ||||||
|  |     p.x = x; | ||||||
|  |     p.y = y; | ||||||
|  |     return p; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Vector2D::normalize(double max) { | ||||||
|  |     lenght_ = (1/lenght_); | ||||||
|  |     point_.x = lenght_ * cos(angle_); | ||||||
|  |     point_.y = lenght_ * sin(angle_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Vector2D Vector2D::reverse() { | ||||||
|  |     Point p; | ||||||
|  |     p.x = -point_.x; | ||||||
|  |     p.y = -point_.y; | ||||||
|  |     return Vector2D(p); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Vector2D Vector2D::operator +(Vector2D v) const { | ||||||
|  |     Point p; | ||||||
|  |     p.x = point_.x + v.x(); | ||||||
|  |     p.y = point_.y + v.y(); | ||||||
|  |     return Vector2D(p); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Vector2D Vector2D::operator -(Vector2D v) const { | ||||||
|  |     Point p; | ||||||
|  |     p.x = point_.x - v.x(); | ||||||
|  |     p.y = point_.y - v.y(); | ||||||
|  |     return Vector2D(p); | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								Vector2D.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								Vector2D.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | #ifndef VECTOR2D_H | ||||||
|  | #define VECTOR2D_H | ||||||
|  |  | ||||||
|  | #include <cmath> | ||||||
|  |  | ||||||
|  | class Vector2D { | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     typedef struct { | ||||||
|  |         double x; | ||||||
|  |         double y; | ||||||
|  |     } Point; | ||||||
|  |     Vector2D() = default; | ||||||
|  |     Vector2D(Point point); | ||||||
|  |     Vector2D(double lenght, double angle); | ||||||
|  |     ~Vector2D() = default; | ||||||
|  |  | ||||||
|  |     static Point CreatePoint(double x, double y); | ||||||
|  |  | ||||||
|  |     double x() {return point_.x;} | ||||||
|  |     double y() {return point_.y;} | ||||||
|  |     Point point() {return point_;} | ||||||
|  |     double lenght() {return lenght_;} | ||||||
|  |     double angle() {return angle_;} | ||||||
|  |  | ||||||
|  |     void normalize(double max); | ||||||
|  |     Vector2D reverse(); | ||||||
|  |  | ||||||
|  |     Vector2D operator +(Vector2D v) const; | ||||||
|  |     Vector2D operator -(Vector2D v) const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Point point_; | ||||||
|  |     double lenght_; | ||||||
|  |     double angle_; | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif //VECTOR2D_H | ||||||
							
								
								
									
										149
									
								
								app.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								app.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | |||||||
|  | #include "app.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | App::App(Stomp* st) { | ||||||
|  |     st_ = st; | ||||||
|  |     st_->connectRequest("sdi.hevs.ch", 61614, "/", "sdi10", "809c02f36becb0868da98761fe3209f6"); | ||||||
|  |     st_->subscribeRequest("/topic/sdi10.gem.field", 1); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::connectConfirmation(bool success, QString version) { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::sendConfirmation(bool success) { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::subscribeConfirmation(bool success) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::receiveIndication(int id, QString destination, QString body) { | ||||||
|  |     //qDebug() << "Indication " << id << " : " << destination << Qt::endl << body << Qt::endl; | ||||||
|  |     if(destination.contains("field")){ | ||||||
|  |         fillField(body); | ||||||
|  |     } | ||||||
|  |     computeMove(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::disconnectConfirmation() { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::disconnectIndication() { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::addGem(int x, int y, int pts) { | ||||||
|  |     Gem g; | ||||||
|  |     g.coordinate = Vector2D(Vector2D::CreatePoint(x, GRID_SIZE-y)); | ||||||
|  |     g.pts = pts; | ||||||
|  |     gems_.append(g); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::fillField(QString body) { | ||||||
|  |     int x = 0; | ||||||
|  |     int y = 0; | ||||||
|  |     gems_.clear(); | ||||||
|  |     for(int i = 0; i<body.length(); i++) { | ||||||
|  |         const QChar c = body.at(i); | ||||||
|  |         if(c == 'Y') { | ||||||
|  |             myVehicle_ = Vector2D(Vector2D::CreatePoint(x, GRID_SIZE-y)); | ||||||
|  |         } | ||||||
|  |         if(c == 'h') { | ||||||
|  |             otherVehicles_.append(Vector2D(Vector2D::CreatePoint(x, GRID_SIZE-y))); | ||||||
|  |         } | ||||||
|  |         if(c == 'g') addGem(x, y, 100); | ||||||
|  |         if(c == 'G') addGem(x, y, 250); | ||||||
|  |         if(c == 'D') addGem(x, y, 500); | ||||||
|  |         if(c == '\n') { | ||||||
|  |             y++; | ||||||
|  |             x = 0; | ||||||
|  |         } else { | ||||||
|  |             x++; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Vector2D App::computeRelativePts(Gem g) { | ||||||
|  |     Vector2D v = g.coordinate-myVehicle_; | ||||||
|  |     v.reverse(); | ||||||
|  |     v.normalize(MAX_LENGHT); | ||||||
|  |  | ||||||
|  |     return Vector2D(v.lenght()*g.pts, v.angle()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::computeRelativeDistance(Gem* g) { | ||||||
|  |     int deltaX = abs(g->coordinate.x() - myVehicle_.x()); | ||||||
|  |     int deltaY = abs(g->coordinate.y() - myVehicle_.y()); | ||||||
|  |     g->relativeDistanceToMe = deltaX+deltaY; | ||||||
|  |     g->relativeDistanceToOtherPlayer = MAX_LENGHT*2; | ||||||
|  |     for(Vector2D v : otherVehicles_) { | ||||||
|  |         deltaX = abs(g->coordinate.x() - v.x()); | ||||||
|  |         deltaY = abs(g->coordinate.y() - v.y()); | ||||||
|  |         if(deltaX+deltaY < g->relativeDistanceToOtherPlayer) { | ||||||
|  |             g->relativeDistanceToOtherPlayer = deltaX+deltaY; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void App::computeMove() { | ||||||
|  |     static const double PI = 3.14159265358979323846; | ||||||
|  |     Vector2D myRelativePts; | ||||||
|  |     for(Gem g : gems_) { | ||||||
|  |         computeRelativeDistance(&g); | ||||||
|  |         Vector2D v = computeRelativePts(g); | ||||||
|  |         myRelativePts = myRelativePts+v; | ||||||
|  |         if(g.relativeDistanceToMe <= g.relativeDistanceToOtherPlayer) { | ||||||
|  |             myRelativePts = myRelativePts+v; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     double angle = myRelativePts.angle(); | ||||||
|  |  | ||||||
|  |     if(angle <0) angle = angle+2*PI; | ||||||
|  |     angle *= 180/PI; | ||||||
|  |  | ||||||
|  |     qDebug() << "Angle: " << angle << "°"; | ||||||
|  |     qDebug() << "Length: " << myRelativePts.lenght() << Qt::endl; | ||||||
|  |  | ||||||
|  |     if(angle > 360) { | ||||||
|  |         qDebug() << "Error angle: " << angle << Qt::endl; | ||||||
|  |     } | ||||||
|  |     else if(angle <= -360) { | ||||||
|  |         qDebug() << "Error angle: " << angle << Qt::endl; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     else if(angle > 315) { // angle > 315° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "right"); | ||||||
|  |     } | ||||||
|  |     else if(angle <= -315) { // angle <= -315° || angle <= 45° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "right"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     else if(angle > 225) { // angle > 225° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "down"); | ||||||
|  |     } | ||||||
|  |     else if(angle <= -225) { // angle <= -225° || angle <= 135° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "up"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     else if(angle > 135) { // angle > 135° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "left"); | ||||||
|  |     } | ||||||
|  |     else if(angle <= -135) { // angle <= -135° || angle <= 225° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "left"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     else if(angle > 45) { // angle > 45° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "up"); | ||||||
|  |     } | ||||||
|  |     else if(angle <= -45) { // angle <= -45° || angle <= 315° | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "down"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     else { | ||||||
|  |         st_->sendRequest("/topic/sdi10.gem.command", "right"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										57
									
								
								app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | #ifndef APP_H | ||||||
|  | #define APP_H | ||||||
|  |  | ||||||
|  | #include <QObject> | ||||||
|  | #include "interface/iStompObserver.h" | ||||||
|  | #include "stomp.h" | ||||||
|  | #include <QVector2D> | ||||||
|  | #include <cmath> | ||||||
|  |  | ||||||
|  | #include "Vector2D.h" | ||||||
|  |  | ||||||
|  | #define GRID_SIZE 32 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class App : public QObject, public interface::iStompObserver { | ||||||
|  | public: | ||||||
|  |     App(Stomp* st); | ||||||
|  |     ~App() = default; | ||||||
|  |  | ||||||
|  |     const double MAX_LENGHT = sqrt(GRID_SIZE*GRID_SIZE + GRID_SIZE*GRID_SIZE); | ||||||
|  |     // iStompObserver interface | ||||||
|  | private: | ||||||
|  |     void connectConfirmation(bool success, QString version); | ||||||
|  |     void sendConfirmation(bool success); | ||||||
|  |     void subscribeConfirmation(bool success); | ||||||
|  |     void receiveIndication(int id, QString destination, QString body); | ||||||
|  |     void disconnectConfirmation(); | ||||||
|  |     void disconnectIndication(); | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     Stomp* st_; | ||||||
|  |  | ||||||
|  |     typedef struct { | ||||||
|  |         Vector2D coordinate; | ||||||
|  |         int relativeDistanceToMe; | ||||||
|  |         int relativeDistanceToOtherPlayer; | ||||||
|  |         int pts; | ||||||
|  |     } Gem; | ||||||
|  |  | ||||||
|  |     typedef struct { | ||||||
|  |         int x; | ||||||
|  |         int y; | ||||||
|  |         bool me; | ||||||
|  |     } Vehicle; | ||||||
|  |  | ||||||
|  |     QVector<Gem> gems_; | ||||||
|  |     Vector2D myVehicle_; | ||||||
|  |     QVector<Vector2D> otherVehicles_; | ||||||
|  |     void addGem(int x, int y, int pts); | ||||||
|  |     void fillField(QString body); | ||||||
|  |     Vector2D computeRelativePts(Gem g); | ||||||
|  |     void computeRelativeDistance(Gem* g); | ||||||
|  |     void computeMove(); | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // APP_H | ||||||
							
								
								
									
										24
									
								
								interface/iStompObserver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								interface/iStompObserver.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | #ifndef ISTOMPOBSERVER_H | ||||||
|  | #define ISTOMPOBSERVER_H | ||||||
|  |  | ||||||
|  | #include <QString> | ||||||
|  |  | ||||||
|  | namespace interface { | ||||||
|  | class iStompObserver { | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     virtual ~iStompObserver() {} | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     iStompObserver() {} | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     virtual void connectConfirmation(bool success, QString version) = 0; | ||||||
|  |     virtual void sendConfirmation(bool success) = 0; | ||||||
|  |     virtual void subscribeConfirmation(bool success) = 0; | ||||||
|  |     virtual void receiveIndication(int id, QString destination, QString body) = 0; | ||||||
|  |     virtual void disconnectConfirmation() = 0; | ||||||
|  |     virtual void disconnectIndication() = 0; | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | #endif // ISTOMPOBSERVER_H | ||||||
							
								
								
									
										36
									
								
								interface/iStompSubject.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								interface/iStompSubject.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | #ifndef ISTOMPSUBJECT_H | ||||||
|  | #define ISTOMPSUBJECT_H | ||||||
|  |  | ||||||
|  | #include "iStompObserver.h" | ||||||
|  | #include <QString> | ||||||
|  |  | ||||||
|  | namespace interface { | ||||||
|  | class iStompSubject { | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     virtual ~iStompSubject() {} | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     iStompSubject() {} | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     virtual bool subscribe(iStompObserver* obs) = 0; | ||||||
|  |     virtual void unsubscribe(iStompObserver* obs) = 0; | ||||||
|  |  | ||||||
|  |     virtual int connectRequest(QString host, int port, QString vhost, QString username, QString password) = 0; | ||||||
|  |     virtual void sendRequest(QString destination, const QByteArray& body) = 0; | ||||||
|  |     virtual void subscribeRequest(QString destination, int id) = 0; | ||||||
|  |     virtual void disconnectRequest() = 0; | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     virtual void notifyConnectConfirmation(bool success, QString version) = 0; | ||||||
|  |     virtual void notifySendConfirmation(bool success) = 0; | ||||||
|  |     virtual void notifySubscribeConfirmation(bool success) = 0; | ||||||
|  |     virtual void notifyReceiveIndication(int id, QString destination, QString body) = 0; | ||||||
|  |     virtual void notifyDisconnectConfirmation() = 0; | ||||||
|  |     virtual void notifyDisconnectIndication() = 0; | ||||||
|  |  | ||||||
|  | }; | ||||||
|  | } // namespace | ||||||
|  |  | ||||||
|  | #endif // ISTOMPSUBJECT_H | ||||||
							
								
								
									
										11
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								main.cpp
									
									
									
									
									
								
							| @@ -1,7 +1,16 @@ | |||||||
| #include <QApplication> | #include <QApplication> | ||||||
|  | #include <QSslSocket> | ||||||
|  | #include <QThread> | ||||||
|  |  | ||||||
|  | #include "stomp.h" | ||||||
|  | #include "app.h" | ||||||
|  |  | ||||||
| int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||||||
|     QApplication application(argc, argv); |     QApplication application(argc, argv); | ||||||
|      |  | ||||||
|  |     Stomp st; | ||||||
|  |     App app(&st); | ||||||
|  |     st.subscribe(&app); | ||||||
|  |  | ||||||
|     return application.exec(); |     return application.exec(); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										157
									
								
								stomp.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								stomp.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | |||||||
|  | #include "stomp.h" | ||||||
|  |  | ||||||
|  | Stomp::Stomp() { | ||||||
|  |     for(int i = 0; i< MAX_OBSERVER; i++) { | ||||||
|  |         observer_[i] = nullptr; | ||||||
|  |     } | ||||||
|  |     socket_.setPeerVerifyMode(QSslSocket::VerifyNone); | ||||||
|  |     QObject::connect(&socket_, &QSslSocket::readyRead, [&] { | ||||||
|  |        STOMPFrame frame = STOMPFrame::receive(socket_); | ||||||
|  |  | ||||||
|  |        switch(frame.command()) { | ||||||
|  |        case STOMPFrame::CONNECTED: | ||||||
|  |            qDebug() << "Connected !" << Qt::endl | ||||||
|  |                    << "Version:" << frame.headers().value("version"); | ||||||
|  |            notifyConnectConfirmation(true,frame.headers().value("version")); | ||||||
|  |            break; | ||||||
|  |  | ||||||
|  |        case STOMPFrame::MESSAGE: | ||||||
|  |            notifyReceiveIndication(1, frame.headers().value("destination"), frame.body()); | ||||||
|  |            //qDebug() << "Message" << Qt::endl; | ||||||
|  |            break; | ||||||
|  |  | ||||||
|  |        case STOMPFrame::RECEIPT: | ||||||
|  |            notifySendConfirmation(true); | ||||||
|  |            qDebug() << "Succesfully send" << Qt::endl; | ||||||
|  |            break; | ||||||
|  |  | ||||||
|  |        case STOMPFrame::ERROR: | ||||||
|  |            notifyConnectConfirmation(false,frame.headers().value("version")); | ||||||
|  |            notifySendConfirmation(false); | ||||||
|  |            qDebug() << Qt::endl | ||||||
|  |                     << "-----ERROR-----" << Qt::endl | ||||||
|  |                     << "Command: " << frame.command() << Qt::endl | ||||||
|  |                     << "Header: " << frame.headers() << Qt::endl | ||||||
|  |                     << "Body: " << frame.body() << Qt::endl | ||||||
|  |                     << Qt::endl; | ||||||
|  |            break; | ||||||
|  |  | ||||||
|  |        default: | ||||||
|  |            qDebug() << Qt::endl | ||||||
|  |                     << "-----Other STOMP frame-----" << Qt::endl | ||||||
|  |                     << "Command: " << frame.command() << Qt::endl | ||||||
|  |                     << "Header: " << frame.headers() << Qt::endl | ||||||
|  |                     << "Body: " << frame.body() << Qt::endl | ||||||
|  |                     << Qt::endl; | ||||||
|  |            break; | ||||||
|  |  | ||||||
|  |        } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::unsubscribe(interface::iStompObserver* obs) { | ||||||
|  |     for(int i = 0; i < MAX_OBSERVER; i++) { | ||||||
|  |         if(observer_[i] == obs) { | ||||||
|  |             observer_[i] = nullptr; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Stomp::connectRequest(QString host, int port, QString vhost, QString username, QString password) { | ||||||
|  |  | ||||||
|  |     socket_.connectToHostEncrypted(host, port); | ||||||
|  |     if(!socket_.waitForConnected()) return -1; | ||||||
|  |  | ||||||
|  |     STOMPFrame(STOMPFrame::STOMP, { | ||||||
|  |         {"accept-version", "1.2"}, | ||||||
|  |         {"host", vhost}, | ||||||
|  |         {"login", username}, | ||||||
|  |         {"passcode", password} | ||||||
|  |     }).send(socket_); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::sendRequest(QString destination, const QByteArray& body) { | ||||||
|  |  | ||||||
|  |     STOMPFrame(STOMPFrame::SEND, { | ||||||
|  |        {"destination", destination}, | ||||||
|  |     }, body).send(socket_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::subscribeRequest(QString destination, int id) { | ||||||
|  |     QString sid = QString::number(id); | ||||||
|  |     STOMPFrame(STOMPFrame::SUBSCRIBE, { | ||||||
|  |         {"destination", destination}, | ||||||
|  |         {"id", sid} | ||||||
|  |     }).send(socket_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::disconnectRequest() { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::notifyConnectConfirmation(bool success, QString version) { | ||||||
|  |     for(int i = 0; i < MAX_OBSERVER; i++) { | ||||||
|  |         if (observer_[i] != nullptr){ | ||||||
|  |             observer_[i]->connectConfirmation(success, version); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::notifySendConfirmation(bool success) { | ||||||
|  |     for(int i = 0; i < MAX_OBSERVER; i++) { | ||||||
|  |         if (observer_[i] != nullptr){ | ||||||
|  |             observer_[i]->sendConfirmation(success); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::notifySubscribeConfirmation(bool success) { | ||||||
|  |     for(int i = 0; i < MAX_OBSERVER; i++) { | ||||||
|  |         if (observer_[i] != nullptr){ | ||||||
|  |             observer_[i]->subscribeConfirmation(success); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::notifyReceiveIndication(int id, QString destination, QString body) { | ||||||
|  |     for(int i = 0; i < MAX_OBSERVER; i++) { | ||||||
|  |         if (observer_[i] != nullptr){ | ||||||
|  |             observer_[i]->receiveIndication(id, destination, body); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::notifyDisconnectConfirmation() { | ||||||
|  |     for(int i = 0; i < MAX_OBSERVER; i++) { | ||||||
|  |         if (observer_[i] != nullptr){ | ||||||
|  |             observer_[i]->disconnectConfirmation(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stomp::notifyDisconnectIndication() { | ||||||
|  |     for(int i = 0; i < MAX_OBSERVER; i++) { | ||||||
|  |         if (observer_[i] != nullptr){ | ||||||
|  |             observer_[i]->disconnectIndication(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										46
									
								
								stomp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								stomp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | #ifndef STOMP_H | ||||||
|  | #define STOMP_H | ||||||
|  |  | ||||||
|  | #include <QObject> | ||||||
|  | #include "interface/iStompSubject.h" | ||||||
|  | #include <QSslSocket> | ||||||
|  | #include "stompframe.h" | ||||||
|  |  | ||||||
|  | #define MAX_OBSERVER 5 | ||||||
|  |  | ||||||
|  | class Stomp : public QObject, public interface::iStompSubject{ | ||||||
|  | public: | ||||||
|  |     Stomp(); | ||||||
|  |     ~Stomp(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     // iStompSubject interface | ||||||
|  | public: | ||||||
|  |     bool subscribe(interface::iStompObserver* obs); | ||||||
|  |     void unsubscribe(interface::iStompObserver* obs); | ||||||
|  |     int connectRequest(QString host, int port, QString vhost, QString username, QString password); | ||||||
|  |     void sendRequest(QString destination, const QByteArray& body); | ||||||
|  |     void subscribeRequest(QString destination, int id); | ||||||
|  |     void disconnectRequest(); | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     void notifyConnectConfirmation(bool success, QString 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]; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     QSslSocket socket_; | ||||||
|  |     QString host_ = "sdi.hevs.ch"; | ||||||
|  |     QString vHost_ = "/"; | ||||||
|  |     int port_ = 61614; | ||||||
|  |     QString user_ = "sdi10"; | ||||||
|  |     QString password_ = "809c02f36becb0868da98761fe3209f6"; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // STOMP_H | ||||||
| @@ -2,21 +2,26 @@ | |||||||
|  |  | ||||||
| STOMPFrame::STOMPFrame(Command command, std::initializer_list<QPair<QString, QString>> headers, const QByteArray& body): | STOMPFrame::STOMPFrame(Command command, std::initializer_list<QPair<QString, QString>> headers, const QByteArray& body): | ||||||
|     command_(command), body_(body) { |     command_(command), body_(body) { | ||||||
|  |  | ||||||
|     for (const auto& header: headers) { |     for (const auto& header: headers) { | ||||||
|         headers_[header.first] = header.second; |         headers_[header.first] = header.second; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| qint64 STOMPFrame::send(QIODevice& device) { | qint64 STOMPFrame::send(QIODevice& device) { | ||||||
|  |  | ||||||
|     QByteArray encoded; |     QByteArray encoded; | ||||||
|     QTextStream out {&encoded}; |     QTextStream out {&encoded}; | ||||||
|     out << command_ << "\n"; |     out << command_ << "\n"; | ||||||
|  |  | ||||||
|     for (const auto& key: headers_.keys()) { |     for (const auto& key: headers_.keys()) { | ||||||
|         out << key << ":" << headers_[key] << "\n"; |         out << key << ":" << headers_[key] << "\n"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!headers_.contains("content-length")) { |     if (!headers_.contains("content-length")) { | ||||||
|         out << "content-length" << ":" << body_.size() << "\n"; |         out << "content-length" << ":" << body_.size() << "\n"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     out << "\n" << body_ << '\0'; |     out << "\n" << body_ << '\0'; | ||||||
|     out.flush(); |     out.flush(); | ||||||
|     return device.write(encoded); |     return device.write(encoded); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user