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();
}
Надеюсь, это будет полезно. (Не пробовал вообще, но собирал)