2016-07-02 30 views
0

私はgsoap libを使用してクライアントサーバーアプリケーションを書いています。問題は、私のserver.iに重いプロセス機能を持たせて、特別なクライアントがこの関数を呼び出すときに、このクライアントの応答が準備ができているときに、この特別なクライアントのためにメッセージを送ります。複数のクライアントが同時にこの関数を呼び出す可能性があります。 qtにasynchronAnswerのようなツールはありますか?どうすればqtやgsoapツールでそれを処理できますか? この問題を処理する真のアーキテクトは何ですか?クライアントの呼び出しでマルチスレッドを使用し、他のスレッドでの応答を待つか、正確にクライアントのIPをサーバなどで呼び出すことができますか? ありがとう、qt非同期クライアントの応答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!"); 
     } 
    } 
} 
#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(); 
} 

とmain.cppには、それが有用でいただければ幸いです。 (まったく味わいませんが、コンパイルしてください)

+0

お返事ありがとうございます...しかし、ここに問題があります。 g soapのようなWebサービスの基本アプリでは、 "sernder"オブジェクトはありません。クライアントを検出するためにクライアントIPを使用するのは大丈夫ですか?それは(スレッドプールを使用して)最良の方法ですか? –

+0

おっと!ここに別の大きな問題があります。ソケットプログラミングサーバーでクライアントにメッセージを送信すると、クライアントはそのメッセージを待ち受けます。 Webサービスプログラミングは、クライアントの要求とサーバーの応答に基づいています。この重い関数をスレッドと応答クライアントに入れたら、私は再び応答できません! –

+0

申し訳ありません。しかし、私はこのコードで "問題"が何を見つけたのか理解できません。どういうわけか別の方法であなた自身を説明できますか? – YouDoItWrong

関連する問題