Subscription message not being received in Qt
-
I am testing a STOMP communication between a Spring Boot server and a Qt desktop program.
The server implementation looks as follows:@Controller class GreetingController { @MessageMapping("/hello") @SendTo("/topic/greetings") @Throws(Exception::class) fun greeting(@RequestBody message : HelloMessage) : Greeting { Thread.sleep(1000); // simulated delay return Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!") } }
The Qt program looks as follows:
bool StompClient::sendFrame(std::shared_ptr<StompFrame> stompFrame) { if (!stompFrame->isBinaryBody()) { QString str = stompFrame->convertToQString(); m_Socket.sendTextMessage(str); qDebug() << "Send stomp frame " << str; return true; } QByteArray ba = stompFrame->convertToByteArray(); m_Socket.sendBinaryMessage(ba); return true; } std::shared_ptr<StompFrame> StompFrameCreator::createSubscribeFrame(const QString& destination) { auto stompFrame = std::make_shared<StompFrame>(); stompFrame->setCommand(StompFrame::HeaderTypes::SUBSCRIBE); stompFrame->addHeader("destination", destination); return stompFrame; } std::shared_ptr<StompFrame> StompFrameCreator::createSendTextFrame(const QString& destination, const QString& message) { auto stompFrame = std::make_shared<StompFrame>(); stompFrame->setCommand(StompFrame::HeaderTypes::SEND); stompFrame->addHeader("destination", destination); stompFrame->addHeader("content-type", "application/json"); stompFrame->addTextBody(message); return stompFrame; } void StompDemoView::sendGreeting() { qDebug() << "Send greeting"; StompFrameCreator stompFrameCreator; QJsonObject jsonObject; jsonObject.insert("name", QJsonValue::fromVariant(m_NameLineEdit->text())); QJsonDocument doc(jsonObject); auto publishFrame = stompFrameCreator.createSendTextFrame("/app/hello", doc.toJson()); qDebug() << "Sending " << doc.toJson(); m_StompClient.sendFrame(publishFrame); } void StompDemoView::clientConnected() { StompFrameCreator stompFrameCreator; qDebug() << "Subscribe to topic"; auto subscribeFrame = stompFrameCreator.createSubscribeFrame(0, "/topic/greetings", "auto"); m_StompClient.sendFrame(subscribeFrame); }
When the client connects to the server I am sending a subscribe request. This is being received by the server:
Decoded SUBSCRIBE {id=[0], destination=[/topic/greetings], ack=[auto]} session=null From client: SUBSCRIBE /topic/greetings id=0 session=6cc3a2b6-48a5-1c1c-2366-d746224d60e8 Processing SUBSCRIBE /topic/greetings id=0 session=6cc3a2b6-48a5-1c1c-2366-d746224d60e8
Then when a user performs a specific action in the GUI I am sending the message to the Greeting controller which should send back a message to the subscribing client:
Decoded SEND {destination=[/app/hello], content-type=[application/json]} session=null application/json payload={ "name": "Cris"
}
From client: SEND /app/hello session=6cc3a2b6-48a5-1c1c-2366-d746224d60e8 application/json payload={ "name": "Cris"
}
Searching methods to handle SEND /app/hello session=6cc3a2b6-48a5-1c1c-2366-d746224d60e8 application/json payload={ "name": "Cris"
}
, lookupDestination='/hello'
Found 1 handler methods: [{[MESSAGE],[/hello]}]
Invoking GreetingController#greeting[1 args]
Arguments: [HelloMessage@3903b632]
Processing return value with SendToMethodReturnValueHandler [annotationRequired=true]
Processing MESSAGE destination=/topic/greetings session=6cc3a2b6-48a5-1c1c-2366-d746224d60e8 payload={"content":"Hello, Cris!"}
Broadcasting to 1 sessions.But I am not receiving anything on the client. I created slots for the signals binaryMessageReceived, textMessageReceived, binaryFrameReceived, textFrameReceived, errorOccured for the QWebSocket used in the communication.
Can anyone point me please in the right direction here ?
-
After using wireshark and a javascript stomp client to compare the websocket messages exchanged between the clients and the server I reached the conclusion that the Qt client did not send a CONNECT Stomp Frame to the server. That is why the server did not send a message corresponding to the subscription, although the client had previously sent a SUBSCRIBE package.
Here is the code in the slot connect to the socketConnected slot of the QWebSocket:
StompFrameCreator stompFrameCreator; auto connectFrame = stompFrameCreator.createConnectFrame("1.2", "", "", "", 10000, 10000); m_StompClient.sendFrame(connectFrame);
After adding that before sending the subscription to the server, the client receives messages pertaining to the subscription from the server.
-
Hi,
You should also add the setup code you use for the web socket.
In the absolute, have a minimal compilable example triggering the issue would be even better.
-
@SGaist
This is the code used for the opening the QWebSocket:void StompDemoView::connectToServer() {
qDebug() << "Connect to server";
m_StompClient.setUrl("ws://localhost:8080/gs-guide-websocket");
m_StompClient.connectToServer();
}void StompClient::setUrl(const QString& url) {
m_Url = url;
}void StompClient::connectToServer() {
if (m_Url.isEmpty())
return;qDebug() << "Connect to " << m_Url; m_Socket.open(m_Url);
}
I could add an archive with the whole project but I am not sure how to do this on this forum.
-
Did you also connect the error management related signals ?
-
@SGaist
I connected the following signals to slots in my class:
errorOccurred, alertReceived, authenticationRequired, handshakeInterruptedOnError, peerVerifyError, proxyAuthenticationRequired,sslErrors, stateChanged,Except for the obvious state changes when connecting and closing the connection and the connect and disconnect signals I am not receiving anything.
For me it seems that the server (running on localhost as well) is sending the messages but somehow they do not arrive to the socket. Is there a way how I can debug this ?
-
After using wireshark and a javascript stomp client to compare the websocket messages exchanged between the clients and the server I reached the conclusion that the Qt client did not send a CONNECT Stomp Frame to the server. That is why the server did not send a message corresponding to the subscription, although the client had previously sent a SUBSCRIBE package.
Here is the code in the slot connect to the socketConnected slot of the QWebSocket:
StompFrameCreator stompFrameCreator; auto connectFrame = stompFrameCreator.createConnectFrame("1.2", "", "", "", 10000, 10000); m_StompClient.sendFrame(connectFrame);
After adding that before sending the subscription to the server, the client receives messages pertaining to the subscription from the server.
-
Nice !
Glad you found out and thanks for sharing :-)
Don't forget to mark the thread as solved :-)
-