2016-07-02 5 views
0

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

+0

Кроме того, попробуйте KDSoap, если у вас есть время. – Velkan

ответ

0

Вы можете попробовать использовать 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(); 
} 

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

+0

привет, спасибо за ваш ответ ... но здесь есть проблема. в базовом приложении веб-сервиса, например g soap, не имеет объекта «sernder». хорошо ли я использовать клиентский ip для обнаружения клиентов? и это лучший способ (используя пул потоков)? –

+0

упс! здесь есть еще одна большая проблема. в сервере программирования сокетов можно послать сообщение для клиента, и клиент будет его слушать. но программирование веб-сервисов основано на запросе клиента и ответе сервера. если я положил эту тяжелую функцию в поток и клиент реакции, я не могу ответить на него снова !!! –

+0

Извините. Но я не могу понять, какие «проблемы» вы нашли в этом коде. Можете ли вы как-то объяснить себя по-другому? – YouDoItWrong