QT实现Thrift C++服务端和客户端

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/signal926/article/details/84966886

效果示例

在这里插入图片描述
本文为了测试和显示方便,将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

猜你喜欢

转载自blog.csdn.net/signal926/article/details/84966886