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
- Apache Thrift - 可伸缩的跨语言服务开发框架
:https://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/ - Thrift C++
服务器和客户端开发实例:https://blog.****.net/feng973/article/details/70160571 - ThriftServer的几种调用模式:https://blog.****.net/sunmenggmail/article/details/46818147
- Thrift多线程调用问题:http://blog.sina.com.cn/s/blog_98cf2a6f0101a1ob.html
- Thrift 双向通信实现(c++版):https://blog.****.net/lwwl12/article/details/77449550