QT實現Thrift C++服務端和客戶端

效果示例

在這裏插入圖片描述
本文爲了測試和顯示方便,將Thrift客戶端和服務端編寫在同一QT程序中,分別開啓一個線程進行交互。

測試操作:
點擊“開啓服務”,開啓Thrift服務端的監聽;在“測試數據”的輸入框中輸入測試消息,點擊“請求服務”發送給服務端進行處理;並把服務端的返回結果顯示在“返回結果”的輸出框中。

QT調用Thrift庫

編譯VS2015 x64版本的Thrift靜態庫,並在QT工程的.pro文件中添加:

INCLUDEPATH 	+= $$PWD \
                   $YOUR_THRIFT_PATH/thrift

LIBS += $YOUR_THRIFT_PATH/thrift/lib/libthrift_x64.lib

如果報boost相關庫的LNK2019錯誤,需要在QT路徑中添加boost庫,如:
把boost的頭文件拷貝到:

$PATH_TO_QT\Qt5.8.0\5.8\msvc2015_64\include\

把boost的庫文件拷貝到:

$PATH_TO_QT\Qt5.8.0\5.8\msvc2015_64\lib\

服務端核心代碼

創建ThriftServer類,繼承自QObject,用於封裝Thrift服務端操作。
點擊UI界面的“開啓服務”,發送信號開啓服務端的監聽,調用ThriftServer類的serve函數。

void ThriftServer::serve()
{
    int port = 9000;
    ::apache::thrift::stdcxx::shared_ptr<PSMPServerHandler> handler(new PSMPServerHandler());
    ::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new PSMPServerProcessor(handler));
    ::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    ::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
    ::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

    m_server = new TSimpleServer(processor, serverTransport, transportFactory, protocolFactory);
    m_server->serve();
}

客戶端核心代碼

創建ThriftClient類,繼承自QObject,用於封裝Thrift客戶端操作。
點擊UI界面的“請求服務”,發送信號開啓服務端的監聽,調用ThriftServer類的serve函數。

void ThriftClient::process(const QString &test_str)
{
    //創建對象
    stdcxx::shared_ptr<TTransport> socket(new TSocket(m_ipAddr, m_nPort));//"127.0.0.1"
    stdcxx::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    qDebug()<<"\nCreate sockets,transports,protocols."<<endl;

    try{
        transport->open();
        qDebug()<<"Transport is open."<<endl;
        m_client = new PSMPServerClient(protocol);
        qDebug()<<"Create client objects."<<endl;

        //構造參數數據
        ImageSearchData searchData;
        searchData.searchData = test_str.toStdString();
        qDebug()<<"Send search data."<<endl;
        Res result;
        m_client->ImageSearch(result,searchData);
        qDebug()<<"Current thread:"<<QThread::currentThreadId()<<endl;
        if(result.errCode==0){
            qDebug()<<"Recv result:"<<QString::fromStdString(result.result)<<endl;
            emit sendResult(QString::fromStdString(result.result));
        }else{
            qDebug()<<"Error code:"<<QString::number(result.errCode)<<endl;
        }

        Sleep(1000);
        transport->close();
    }
    catch(TException& e){
        qDebug()<<"Error:"<<e.what()<<endl;
    }
}

開啓服務端、客戶端線程

在主線程中創建ThriftServer、ThriftClient類的成員變量,分別綁定一個QThread線程進行交互,實現在單個應用程序中對服務端、客戶端的測試。

	m_TServer = new ThriftServer;
    m_TServer->moveToThread(&m_thrdServer);
    connect(&m_thrdServer, &QThread::finished, m_TServer, &QObject::deleteLater);
    connect(ui->btnStartServer,&QPushButton::clicked,m_TServer,&ThriftServer::serve);
    m_thrdServer.start();

    m_TClient = new ThriftClient;
    m_TClient->moveToThread(&m_thrdClient);
    connect(&m_thrdClient, &QThread::finished, m_TClient, &QObject::deleteLater);
    connect(this,&MainWindow::start,m_TClient,&ThriftClient::init);
    connect(this,&MainWindow::send,m_TClient,&ThriftClient::process);
    connect(m_TClient,&ThriftClient::sendResult,this,&MainWindow::recv_results);
    m_thrdClient.start();

Reference

  1. Apache Thrift - 可伸縮的跨語言服務開發框架
    https://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/
  2. Thrift C++
    服務器和客戶端開發實例:https://blog.csdn.net/feng973/article/details/70160571
  3. ThriftServer的幾種調用模式:https://blog.csdn.net/sunmenggmail/article/details/46818147
  4. Thrift多線程調用問題:http://blog.sina.com.cn/s/blog_98cf2a6f0101a1ob.html
  5. Thrift 雙向通信實現(c++版):https://blog.csdn.net/lwwl12/article/details/77449550
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章