2016-07-02 11 views
0

Ich schreibe Client-Server-Anwendung mit gsoap lib. Das Problem ist, dass eine schwere Prozess-Funktion in meinem Server.Ich möchte, wenn spezielle Client diese Funktion aufrufen, die Server-Nachricht für diesen speziellen Client senden, dass "Ihre Antwort bereit ist", wenn diese Client-Antwort bereit ist. und es ist möglich, dass mehrere Clients diese Funktion gleichzeitig aufrufen. gibt es irgendein Werkzeug wie asynchronAnswer in qt? und wenn nicht, wie kann ich mit Qt oder Gsoap tools umgehen? was ist der wahre Architekt der Umgang mit diesen Problemen? Verwenden Sie Multi-Thread in Client-Aufruf und warten auf Antwort in anderen Thread oder genau Call-Client durch seine IP in Server oder etwas Besseres? danke,qt asynchrone Clients Antwort gsoap

+0

Versuchen Sie auch KDSoap, wenn Sie Zeit haben. – Velkan

Antwort

0

Sie können versuchen, QWebSocket für diese Aufgabe zu verwenden. Sie haben eine Client-Liste verbunden, wenn der Client eine Anfrage für eine "schwere Prozessfunktion" sendet, Sie den Thread-Pool einsetzen und nach Abschluss der Berechnungen eine Wiederholung an den bestimmten Client senden. Im Code wird es so etwas wie dieses:

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

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

Hoffe, dass es nützlich sein wird. (Nicht geschmeckt, aber kompilieren)

+0

Hallo, danke für deine Antwort ... aber es gibt ein Problem hier. in Web-Service-Basis-App wie g Soap ein "sender" -Objekt haben. Ist es in Ordnung, Client-IP für die Erkennung von Clients zu verwenden? und ist es der beste Weg überhaupt (mit Thread-Pool)? –

+0

oops! Es gibt ein anderes großes Problem hier. im Socket-Programming-Server kann eine Nachricht für den Client gesendet werden und der Client wird darauf hören. Die Web-Service-Programmierung basiert jedoch auf der Client-Anfrage und der Server-Antwort. Wenn ich diese schwere Funktion in Thread und Antwort-Client, kann ich nicht noch einmal antworten !!! –

+0

Entschuldigung. Aber ich kann nicht verstehen, welche "Probleme" du in diesem Code gefunden hast. Kannst du dich irgendwie anders erklären? – YouDoItWrong