Thrift 입문-RPC 서비스 사용

17592 단어 C++
Thrift 는 언어 를 뛰 어 넘 는 서비스 배치 프레임 워 크 로 성능 이 우수한 직렬 화/반 직렬 화 기능 을 제공 하 는 동시에 RPC 서 비 스 를 제공 합 니 다.Protocol buffers 에 비해 지원 하 는 언어 가 더욱 광범 위 합 니 다.본 고 는 Thrift 의 RPC 를 사용 하여 client 와 server 간 의 통신 을 실현 하 는 것 을 소개 한다.Thrift 에 대한 소개 와 문법 설명 은 문헌[1-2]을 참조 할 수 있다.
본 고 는 정 의 된 Thrift 문법 구 조 를 통 해 Thrift 컴 파일 러 가 자동 으로 생 성 된 server 엔 드 서비스 인터페이스 코드 와 client 엔 드 파일 코드 를 사용 하여 client 가 server 엔 드 에서 제공 하 는 서비스 인 터 페 이 스 를 호출 하여 주어진 인원 의 city 정 보 를 조회 하 는 데 목적 을 둔다.client 측 에서 요청 한 매개 변 수 는 여러 사람의 ID 와 이름 을 포함 합 니 다.server 엔 드 처리 후 미리 정 의 된 데이터 구 조 를 통 해 client 에 응답 합 니 다.
1.요청 과 응답 데이터 구조,서비스 인터페이스 정의
//InfoQuery.thrift
namespace cpp com.test.infoquery  // cpp ,             
namespace java com.test.infoquery // java ,         package 

struct RequestData
{
    1: required i32 id;
    2: required string name;
}
//client          
struct Instruction
{
    1: required string taskid;
    2: required list requestData;
}

struct ResponseData
{
    1: required string name;
    2: required string city;
}
//             
struct InstructionResult
{
    1: required string taskid;
    2: list responseData;
}

//    
service WTWServ
{
    /*
     *reqService:       ,client        service     
     *Instruction:client    ,       
     *InstructionResult:serve       
     */
    InstructionResult reqService(1: Instruction ins );
}

'thrift–gen'을 통 해 직렬 화 및 RPC 호출 클 라 이언 트 와 서버 인터페이스 코드 등 을 자동 으로 생 성 합 니 다.그 중"WTWServserver.skeleton.cpp 는 간단 한 서버 코드 를 제공 하여 사용자 정의 수 요 를 만족 시 킬 수 있 습 니 다.
# thrift --gen cpp InfoQuery.thrift
# tree gen-cpp/
gen-cpp/
├── InfoQuery_constants.cpp
├── InfoQuery_constants.h
├── InfoQuery_types.cpp
├── InfoQuery_types.h
├── WTWServ.cpp
├── WTWServ.h
└── WTWServ_server.skeleton.cpp

2.client 엔 드 코드
#include "WTWServ.h"
#include 
#include 
#include 
#include 

#include 
#include //add
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using boost::shared_ptr;
using namespace  ::com::test::infoquery;
using namespace std;

bool sendQuery(Instruction & inst, WTWServClient & client)
{
    InstructionResult ret; //      server    
    try{
        client.reqService(ret,inst);  //     service    ,     
    }catch(TProtocolException& tx){
        cout<<"Connect TProtocol  error!  "<return false;
    }catch(TException& tx){
        cout<<"Send error!  "<return false;
    }
    cout<<"Get the result:"<for(size_t i = 0 ;i < (ret.responseData).size() ; ++i){
        cout<<"name:"<"; city:"<return true;
}

int main(int argc, char **argv) {
    int port = 9090;
    string strHost = "127.0.0.1";

    shared_ptr socket(new TSocket(strHost,port));
    shared_ptr transport(new TFramedTransport(socket));
    shared_ptr protocol(new TBinaryProtocol(transport));
    WTWServClient client(protocol);

    try {
        transport->open();
        cout<<"connect established"<catch(TException& tx){
        cout<<"Connect error!  "<return -1;
    }

    RequestData s1,s2;
    vector vecInfo;

    s1.id = 100;
    s1.name = "jacky";
    vecInfo.push_back(s1);

    s2.id = 200;
    s2.name = "king";
    vecInfo.push_back(s2);

    Instruction inst;
    inst.__set_taskid("query_task_01");
    inst.__set_requestData(vecInfo);

    if(sendQuery(inst,client)){
        cout<<"query success ..."<return 0;
}

우선,전송 채널 TCP 링크 의 구축 과 클 라 이언 트 의 생 성 을 보십시오.
shared_ptr socket(new TSocket(strHost,port));
shared_ptr transport(new TFramedTransport(socket));
shared_ptr protocol(new TBinaryProtocol(transport));
WTWServClient client(protocol);
transport->open();

목적 호스트 의 IP 와 포트 를 사용 하여 socket 을 구성 합 니 다.TSocket 은 TCP 프로 토 콜 로 데이터 전송 을 합 니 다.이때 socket 대상 은 아직 진정한 링크 를 만 들 지 않 았 습 니 다.TFramed Transport 는 전송 효율 을 높이 기 위해 socket 대상 을 포장 할 것 이다.TFramed Transport 는 보 낼 데 이 터 를 캐 시 합 니 다.flush 작업 이 호출 될 때 까지 전체 바 이 너 리 데이터 블록 을 보 냅 니 다.다른 쪽 수신 자 는 항상 고정 길이 의 데 이 터 를 읽 을 수 있 습 니 다.유사 한 전송 방식 은 TBuffered Transport,Tmemory Buffer 참조 헤더 파일 도 있 습 니 다.
"thrift/transport/TBufferTransports.h"

TProtocol 은 상기 포장 후(주어진 전송 방식 의 socket)전송 대상 에 사용 할 인 코딩 방식 을 정의 합 니 다.TBinary Protocol 은 바 이 너 리 전송 으로 전송 할 모든 데 이 터 는 기본 바 이 너 리 형식 으로 전 송 됩 니 다.유사 한 인 코딩 으로 는 TJSONprotocol,TCompactprotocol,TDebugProtocol 도 있다.TTransport 의 open()방법 을 사용 해 야 진정한 TCP 링크 를 만 들 수 있 습 니 다.WTWServClient 클래스 는 Thrift 가 정의 에 따라 전송 데이터 구 조 를 클 라 이언 트 로 자동 으로 생 성 합 니 다."WTWServ.h"참조.이러한 중요 한 방법 중 하 나 는 reqService 이다.
void reqService(InstructionResult& _return, const Instruction& ins);

void reqService(InstructionResult& _return, const Instruction& ins); 이것 은 요청 파 라 메 터 를 제공 하고 서버 의 귀환 을 기다 리 는 차단 방법 입 니 다.정 의 된 sendQuery 함수 에서 사용 방법 을 알려 주 었 습 니 다.RequestData 와 Instruction 클래스 는 Thrift 가 사용자 정의 데이터 구조 인 InfoQuery.thrift 에 따라 자동 으로 생 성 됩 니 다.구성원 변 수 는 기본적으로 공유 속성 으로 직접 접근 할 수 있 으 며''을 통 해set"시작 하 는 공유 방법 설정 은"InfoQuery "에 있 습 니 다.types.h”。
3.server 엔 드 코드
자동 으로 생 성 되 는"WTWServ"server.skeleton.cpp'이름 을'server.cpp'로 바 꾸 고 사용자 정의 수 요 를 만족 시 키 기 위해 변경 합 니 다.

#include "WTWServ.h"
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 


using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using namespace std;
using boost::shared_ptr;
using namespace  ::com::test::infoquery;
using namespace ::apache::thrift::concurrency;
class WTWServHandler : virtual public WTWServIf {
    public:
    WTWServHandler() {
    }

    void reqService(InstructionResult& _return, const Instruction& ins) {

        cout<<"Query task id:"<vector vecInfo;
        for(size_t i = 0 ;i < (ins.requestData).size() ; ++i){
            ResponseData rsp;
            rsp.name = (ins.requestData)[i].name;
            if((ins.requestData)[i].id == 100){
                rsp.city = "Nanjing";
            } else {
                rsp.city = "NULL";
            }
            vecInfo.push_back(rsp);
        }
        _return.__set_responseData(vecInfo);
        cout<<"Query deal success ..."<int main(int argc, char **argv) {
    int port = 9090;
    shared_ptr handler(new WTWServHandler());
    shared_ptr processor(new WTWServProcessor(handler));
    shared_ptr serverTransport(new TServerSocket(port));
    shared_ptr transportFactory(new TFramedTransportFactory());
    shared_ptr protocolFactory(new TBinaryProtocolFactory());

    shared_ptr threadManager = ThreadManager::newSimpleThreadManager(15);
    shared_ptr threadFactory = shared_ptr (new PosixThreadFactory()); 
    threadManager->threadFactory(threadFactory);
    threadManager->start();

    TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager);
    server.serve();

    cout<<"service start..."<return 0;
}

WTWServHandler 클래스 는 Thrift 가'InfoQuery.thrift'에 의 해 정 의 된 service 에 따라 자동 으로 생 성 됩 니 다.클 라 이언 트 요청 에 대한 처 리 를 정의 하 는 reqService 방법 이 필요 합 니 다.다음은 server 대상 을 만 드 는 데 필요 한 인 자 를 통 해 server 를 만 드 는 데 필요 한 대상 을 만 듭 니 다.TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager); TProcessor:동작 에 대한 요청/응답 처리 자 는 입 출력 데이터 흐름 에 의존 합 니 다.TServer Transport:서버 전송 에 사용 되 는 전송 방식 입 니 다.TServer Socket 은 서버 가 TCP 의 지정 한 port 포트 로 서 비 스 를 개방 하 는 것 을 말 합 니 다.TTransportFactory:전송 방식 은 client 단 TFramed Transport 전송 방식 에 대응 합 니 다.TBinary ProtocolFactory:인 코딩 방식,즉 바 텀 에서 ThreadManager 를 바 이 너 리 로 전송 합 니 다.서버 에 설 치 된 스 레 드 관리자 입 니 다.PosixThreadFactory 를 통 해 스 레 드 대상 을 만 듭 니 다.
4.실행
# tree .
├── client
│   ├── client.cpp
│   ├── InfoQuery_constants.cpp
│   ├── InfoQuery_constants.h
│   ├── InfoQuery_types.cpp
│   ├── InfoQuery_types.h
│   ├── WTWServ.cpp
│   └── WTWServ.h
├── InfoQuery.thrift
└── server
    ├── InfoQuery_constants.cpp
    ├── InfoQuery_constants.h
    ├── InfoQuery_types.cpp
    ├── InfoQuery_types.h
    ├── server.cpp
    ├── WTWServ.cpp
    └── WTWServ.h

client 와 server 디 렉 터 리 에 각각 코드 를 컴 파일 합 니 다:
g++ -g *.cpp -o server -DHAVE_NETINET_IN_H  -I ./ -lthrift -lpthread -lrt

먼저 server 엔 드 를 시작 한 다음 클 라 이언 트 엔 드 를 시작 합 니 다:
1.Thirft 프레임 워 크 소개 2.Thrift 사용 안내

좋은 웹페이지 즐겨찾기