Qt Asynchron Clients Response Gsoap

Я пишу клиент-серверное приложение, используя gsoap lib. проблема в том, что у меня на сервере тяжелая функция процесса. Я хочу, чтобы, когда специальный клиент вызывал эту функцию, сервер отправлял сообщение для этого специального клиента, что "ваш ответ готов", когда этот ответ клиента готов. и возможно, что несколько клиентов вызывают эту функцию одновременно. Есть ли такой инструмент, как asynchronAnswer в Qt? и если нет, то как я могу справиться с этим с помощью инструментов qt или gsoap? Каков истинный архитектор для решения этих проблем? использование многопоточности в вызове клиента и ожидание ответа в другом потоке или точный вызов клиента по его ip в сервере или что-то лучше? Спасибо,

1 ответ

Вы можете попробовать использовать QWebSocket для этой задачи. Вы подключили список клиентов, если клиент отправляет запрос на "тяжелую функцию процесса", вы помещаете в пул потоков и отправляете воспроизведение определенному клиенту после выполнения вычислений. В коде это будет примерно так:

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!");
        }
    }
}

и 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();
}

Надеюсь, это будет полезно. (Не пробовал вообще, но собирал)

Другие вопросы по тегам