qt asynchron clients response gsoap

275 Views Asked by At

i am writing client server application using gsoap lib. the problem is that a have a heavy process function in my server.i want to when special client call this function, the server send message for this special client that "your answer is ready" when this client answer is ready. and its possible that multiple client call this function in same time. is there any tool like asynchronAnswer in qt? and if not how can i handle it with qt or gsoap tools? whats the true architect of handle this problems? using multi thread in client calling and wait for response in other thread or exactly call client by its ip in server or something better? thanks,

1

There are 1 best solutions below

4
AudioBubble On

You can try to use QWebSocket for this task. You have connected client list, if client send a request for "heavy process function", you are puting in thread pool, and sending replay to the specific client after calculations are done. In code it will be something like this:

server.h

#ifndef SERVER_H
#define SERVER_H

#include <QObject>
#include <QtWebSockets>

class Server : public QObject
{
    Q_OBJECT
public:
    explicit Server(QObject *parent = 0);
    ~Server();
signals:
    void closed();
public slots:
private slots:
    void onNewConnection();
    void onMessage(QString message);
    void onDisconnected();
private:
    QWebSocketServer* m_pWebSocketServer;
    QList<QWebSocket*> m_clients;
};

#endif // SERVER_H

server.cpp

#include <QThreadPool>

#include "server.h"
#include "heavytask.h"

Server::Server(QObject *parent) :
    QObject(parent),
    m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Server"), QWebSocketServer::NonSecureMode, this))
{
    if (m_pWebSocketServer->listen(QHostAddress::Any, 4000)) {
        connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &Server::onNewConnection);
        connect(m_pWebSocketServer, &QWebSocketServer::closed, this, &Server::closed);
    }
}

void Server::onNewConnection()
{
    QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
    connect(pSocket, &QWebSocket::textMessageReceived, this, &Server::onMessage);
    connect(pSocket, &QWebSocket::disconnected, this, &Server::onDisconnected);

    m_clients << pSocket;
}

void Server::onMessage(QString message)
{
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());

    if (message == "Start heavy process function in your server, please") {
        HeavyTask* ht = new HeavyTask(pClient);
        QThreadPool::globalInstance()->start(ht);
    }
}

void Server::onDisconnected()
{
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
    if (pClient) {
        m_clients.removeAll(pClient);
        pClient->deleteLater();
    }
}

Server::~Server()
{
    m_pWebSocketServer->close();
    qDeleteAll(m_clients.begin(), m_clients.end());
}

heavytask.h

#ifndef HEAVYTASK_H
#define HEAVYTASK_H

#include <QThreadPool>
#include <QRunnable>
#include <QWebSocket>

class HeavyTask : public QRunnable
{
public:
    explicit HeavyTask(QWebSocket* client);
    void run();
private:
    QWebSocket* m_client;
};

#endif // HEAVYTASK_H

heavytask.cpp

#include "heavytask.h"

HeavyTask::HeavyTask(QWebSocket* client) : m_client(client)
{
}

void HeavyTask::run()
{
    /*
    Do your havy task;
    */

    if (m_client != nullptr) {
        if (m_client->isValid()) {
            m_client->sendTextMessage("Your answer is ready!");
        }
    }
}

and main.cpp

#include <QCoreApplication>
#include "server.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Server server(&a);
    QObject::connect(&server, &Server::closed, &a, &QCoreApplication::quit);
    return a.exec();
}

Hope it'll be useful. (Not tasted at all, but compiling)