[SOLVED]Communicating application shutdown
-
I have an application "A" and I am trying to communicate to application "B
that "A" is shutting down. The following code shows what I am trying to sendvoid TapDisplay::aboutToQuitApp() { // Send an EXIT command to Tap Engine TapUserEventMessage* exit_message = new TapUserEventMessage(TapRequestAction::EXIT); emit outboundEngineData(exit_message); // This is where we clean up due to a signal from the main application that // we are shutting down if (engine_comm_handler) { engine_comm_handler->close(); } }
The problem is, I think the "A" is shutting down before the message has a chance to be sent to "B". The message is not being sent by "A", and thus "B" is unaware that "A" has gone away. The communication is occurring over a socket connection
Is there a better way to do this, so that I have enough time for message propagation to "B" before pulling the plug on "A"?
Thanks!
-Dave -
Is application "B" in your hands as well ?
If yes, when closing the socket properly, application "B" will get a socket error "QAbstractSocket::RemoteHostClosedError", when the socket is closed by any means by application "A".
From your code this seems to be a sufficient information, cause there's not something like a "reason" - like "User pressed closed button" - transmitted.
Or am I wrong ?
-
I can't use the loss of socket connection as an exit trigger. Under normal operations, the connection can be lost. In that case I don't want the Application "B" to close. When a connection is re-established from application "A", data will resume flowing. Only willfully closing application "A" should send the exit signal to application "B". I need to have that EXIT message sent successfully.
-
You can overide the method closeEvent of the widget.
void MainWindow::closeEvent(QCloseEvent* event)
{
// your code here
event->accept();
}If you don't want it to close for some reasons, simply replace the accept() call with event->ignore();
-
I am not using widgets, it's a QtQuick application.
-
Hi,
a solution could be send the message synchronously (without using signals)
void TapDisplay::aboutToQuitApp() { // Send an EXIT command to Tap Engine TapUserEventMessage* exit_message = new TapUserEventMessage(TapRequestAction::EXIT); // Some method that returns after the message is sent engine_comm_handler->sendMessage(exit_messsge); // This is where we clean up due to a signal from the main application that // we are shutting down if (engine_comm_handler) { engine_comm_handler->close(); } }
-
Do you have an application layer acknowledgement of messages in your protocol ?
If yes, take the acknowledge of the exit message as a trigger for an exit signal, which may be connected to some slot calling exit on the application.
Leads to the question, what to do, if the acknowledge timeouts ...If no, I guess that there's not any chance to know, whether the message arrived at application "B" or not.
Even awaitForBytesWritten
on the socket layer returns usually when the data are written to the internal TCP/IP buffer of the OS, and not when the data arrived the peer. -
@mcosta Thank you! That seems to have mostly done the trick. I had to also add a call to flush() on the socket to make sure the transfer occurred. It's working fine now.
Thanks!