效果示例
本文爲了測試和顯示方便,將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
- Apache Thrift - 可伸縮的跨語言服務開發框架
:https://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/ - Thrift C++
服務器和客戶端開發實例:https://blog.csdn.net/feng973/article/details/70160571 - ThriftServer的幾種調用模式:https://blog.csdn.net/sunmenggmail/article/details/46818147
- Thrift多線程調用問題:http://blog.sina.com.cn/s/blog_98cf2a6f0101a1ob.html
- Thrift 雙向通信實現(c++版):https://blog.csdn.net/lwwl12/article/details/77449550