模拟生产环境使用thrift c++版

来源:互联网 发布:淘宝店麻辣小黑粉 编辑:程序博客网 时间:2024/05/17 08:12

模拟生产环境使用thrift c++版

1. 简介

本文简单的模拟了实际生成环境场景中使用的C/S模型,使用thrift作为框架来进行开发,服务端实现了两个接口,使用ThreadPoolServer模型提供服务,由于只是学习thrift相关的使用,本文的代码不是很严谨,代码设计基本没有,请阅读本文之前最好有基本的thrift相关的知识。如
* thrift文件中的基本数据类型
* thrift文件中的简单的结构体定义
* 如何用thrift文件生成代码

2. thrift文件

在生成环境中,每次调用rpc都必须要有返回值,以标识rpc在业务层面的成功与否。
本次实验定义了一个通用返回结构体,由于thrift文件支持包含语法,所以将该结构体
定义在comm.thrift文件中,用于被其他thrift文件包含
comm.thrift:

struct ReturnMessage{    1: i32 ret_code;    2: string ret_msg}

业务接口和接口定义test.thrift文件:

include "comm.thrift"namespace cpp xbshop.manage.loginstruct ReqLoginService{    1: string strUserName;    2: string strPassword;}//req+服务名定义的结构体代表该服务的请求参数,res+服务名定义的结构体代表该服务的返回参数struct ResLoginService{    1: comm.ReturnMessage stReturnMessage, //注意使用包含文件中定义的结构体时,需要加上文件名前缀,例如使用comm.thrfit文件中的结构体,需要加上comm.    2: bool logged}struct ReqQryOrderService{    1: string order_no;}struct ResQryOrderService{    1: comm.ReturnMessage stReturnMessage,    2: i64 total_fee;}//定义了两个服务,一个是LoginService登录服务,一个是QyrOrderService查询订单服务service LoginService{    comm.ReturnMessage login(1: ReqLoginService reqParams);}service QryOrderService{    ResQryOrderService qryOrder(1: ReqQryOrderService reqParams);}

使用命令thrift -r –gen cpp test.thrift , -r参数的含义是编译test.thrift文件的同时还会编译其包含文件comm.thrift

服务端代码

#include "LoginServiceHandle.h"#include "QryOrderService.h"#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/server/TThreadPoolServer.h>#include <thrift/transport/TServerSocket.h>#include <thrift/transport/TBufferTransports.h>#include "thrift/processor/TMultiplexedProcessor.h"#include "thrift/server/TSimpleServer.h"#include "concurrency/PosixThreadFactory.h"#include "concurrency/ThreadManager.h"using namespace ::apache::thrift;using namespace ::apache::thrift::protocol;using namespace ::apache::thrift::transport;using namespace ::apache::thrift::server;using namespace ::apache::thrift::concurrency;using boost::shared_ptr;using namespace  ::xbshop::manage::login;int main(int argc, char **argv) {  int port = 9090;  shared_ptr<LoginServiceHandler> handler(new LoginServiceHandler());  shared_ptr<QryOrderServiceHandler> spQryOrderServiceHandler(new QryOrderServiceHandler());  shared_ptr<TProcessor> spLoginProcessor(new LoginServiceProcessor(handler));  shared_ptr<TProcessor> spQryOrderServiceProcessor(new QryOrderServiceProcessor(spQryOrderServiceHandler));  shared_ptr<TServerTransport> serverTransport(new TServerSocket("127.0.0.1", port));  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());  shared_ptr<TMultiplexedProcessor> cMultiProcessor(new TMultiplexedProcessor());  cMultiProcessor->registerProcessor("LoginService", spLoginProcessor);  cMultiProcessor->registerProcessor("QryOrderService", spQryOrderServiceProcessor);  shared_ptr<ThreadManager> spThreadManager(ThreadManager::newSimpleThreadManager(10));  shared_ptr<ThreadFactory> spPthreadFactory(new PosixThreadFactory());  spThreadManager->threadFactory(spPthreadFactory);  spThreadManager->start();  TThreadPoolServer server(cMultiProcessor, serverTransport, transportFactory, protocolFactory, spThreadManager);  server.serve();  return 0;}

如果服务端需要定义多个服务,需要使用TMultiplexedProcessor类注册多个processor。
如果要使用TThreadPoolServer服务模型,必须自己定义一个ThreadManager,并调用start函数,不然客户端调用rpc时会抛异常.服务端代码中的LoginServiceHandle.h和LoginServiceHandle.cpp是自己新建的,在生产环境中一个service的代码文件肯定是单独存放的,而自动生成的代码文件中handle与main函数是放在一起的
LoginServiceHandle.h

#ifndef _LOGIN_SERVICE_HANDLE_H#define _LOGIN_SERVICE_HANDLE_H#include "LoginService.h"using namespace  ::xbshop::manage::login;class LoginServiceHandler : virtual public LoginServiceIf {public:    LoginServiceHandler();    void login(::ReturnMessage& _return, const ReqLoginService& reqParams);};#endif

LoginServiceHandle.cpp

#include "LoginServiceHandle.h"LoginServiceHandler::LoginServiceHandler(){}void LoginServiceHandler::login(::ReturnMessage& _return, const ReqLoginService& reqParams){    _return.ret_code = 0;    _return.ret_msg = "ok";}

QryOrderService的实现

QryOrderServiceHandler::QryOrderServiceHandler(){}void QryOrderServiceHandler::qryOrder(ResQryOrderService& _return, const ReqQryOrderService& reqParams){    if (reqParams.order_no == "123")    {        _return.stReturnMessage.ret_code = 0;        _return.stReturnMessage.ret_msg = "ok";        _return.total_fee = 100;    }    else    {        _return.stReturnMessage.ret_code = -1;        _return.stReturnMessage.ret_msg = "order_no error";        _return.total_fee = 0;    }}

客户端代码

#include <stdio.h>#include "LoginServiceHandle.h"#include "QryOrderService.h"#include "test_types.h"#include "transport/TSocket.h"#include "transport/TBufferTransports.h"#include "protocol/TBinaryProtocol.h"#include "protocol/TMultiplexedProtocol.h"using namespace apache::thrift;using namespace apache::thrift::protocol;using namespace apache::thrift::transport;using boost::shared_ptr;using namespace  ::xbshop::manage::login;int main(){    shared_ptr<TSocket> socket(new TSocket("127.0.0.1", 9090));    shared_ptr<TTransport> transport(new TBufferedTransport(socket));    shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));    transport->open();    shared_ptr<TMultiplexedProtocol> cMp1(new TMultiplexedProtocol(protocol, "LoginService"));    shared_ptr<TMultiplexedProtocol> cMp2(new TMultiplexedProtocol(protocol, "QryOrderService"));    ReqQryOrderService stReqParams;    QryOrderServiceClient cQryOrderClient(cMp2);    ResQryOrderService stResParams;    stReqParams.order_no = "123";    cQryOrderClient.qryOrder(stResParams, stReqParams);    printf("%d %s\n", stResParams.stReturnMessage.ret_code, stResParams.stReturnMessage.ret_msg.c_str());    printf("%d\n", stResParams.total_fee);    transport->close();    return 0;}

相应的客户端要使用多个service,需要用到TMultiplexedProtocol类,用来初始化相应service的客户端。

0 0
原创粉丝点击