使用Apache Thrift实现具有HTTP协议的服务器/客户端

时间:2016-08-01 21:30:37

标签: c++ apache rpc thrift-protocol

我是apache节俭的新手。我想用它来帮助我实现一个服务器,它接受来自客户端的输入,解析它并根据它将它指向正确的函数,然后该函数将返回对该特定请求的响应。

例如:

  1. 客户端发送:/ get_list / 1(这应该从服务器返回列表#1中的值)
  2. 服务器将输入解析为以下内容:get_list&& 1
  3. 服务器将此映射到get_list_req,这是一个只有一个参数的结构:i32_t id(在本例中为1)
  4. 服务器将此发送到getListReq函数,该函数应返回get_list_resp结构,该结构有1个参数:list list_content。
  5. 现在我已经在mylist.thrift中定义了必要的结构:

    struct TGetListRequest {
        1: i32_t id,
    }
    struct TGetListResponse {
        1: string response_code, //FAIL or SUCCESS
        2: list<string> nodes, 
    }
    
    service TmyListService {
    
        TGetListResponse getListReq( 1:TGetListRequest arg ),
    }
    

    现在生成必要的文件:

    TmyListService_server.skeleton.cpp 
    TmyListService.cpp
    TmyListService.h
    mylistconstants.cpp
    mylistconstants.h
    mylisttypes.cpp
    mylisttypes.h
    

    将第一个文件的内容复制到TmyListService_server.cpp,其中的类使用其方法实现:getListReq,如下所示:

    class TGetListRequestHandler: public TGetListRequestIf {
    public:
        TGetListResponse getListReq(TGetListRequest arg){
            ...
        }
    };
    

    我在其中提供了以下代码以在main()函数中启动服务器:

    int main(int argc, char **argv)  {
      int port = 9090;
      shared_ptr<TmyListServiceHandler> handler(new TmyListServiceHandler());
      shared_ptr<TProcessor> processor(new TmyListServiceProcessor(handler));
      shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
      shared_ptr<TTransportFactory> transportFactory(new  TBufferedTransportFactory());
      shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
    
      TSimpleServer server(processor, serverTransport, transportFactory,     protocolFactory);
      server.serve();
      return 0;
    }
    

    现在对我来说是棘手的部分:

    1. 我在哪里实现从客户端到服务器的输入解析?我被告知使用thrift是简单的实现,而无需编写我们的解析器或使用解析器生成器?我似乎无法想出这一个?我在哪里告诉我的服务器如何处理输入,即将其指向哪个Req功能?

    2. 在实施客户方面,我有以下内容:

      int main(int argc, char **argv) {
       boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
       boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
       boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
      
       TmyListServiceClient client(protocol);
       TGetListRequest arg;
       arg.id = 1;
       TGetListResponse argz;
       transport->open();
       client.send_getListReq( arg );
       printf("DONE SEDNING");
       client.recv_getListReq( argz );
       transport->close();
      
      return 0;
      }
      
    3. 除了打开客户端连接之外,这基本上没有任何作用。它根本不接受任何输入。我确信这也与服务器中的处理逻辑的实现有关,但是我应该在这里做些什么来准备客户端对服务器进行测试?

1 个答案:

答案 0 :(得分:1)

你差不多完成了!

在您的服务器上显示以下代码:

shared_ptr<TProcessor> processor(new TmyListServiceProcessor(handler));

处理程序在哪里?!这是实现您的服务的类。

类似的东西:

class TmyListServiceHandler: public TmyListServiceIf { public: virtual TGetListResponse getListReq(TGetListRequest arg) override { } };

服务的基础(TmyListServiceIf)在以下位置生成:TmyListService.h

&GT;

查看您对我认为您仍然拥有的问题所做的修改 处理程序问题。声明Handler类:TGetListRequestHandler 在您添加的新代码中。

然而,您正在构造主函数中的TmyListServiceHandler 服务器。当人们改变IDL中的东西时,我已经看到了这种情况 并重新生成代码而不删除旧输出。你最终得到了两个 事物的不同定义。您需要使用TmyListServiceHandler 到处。

根据你的IDL,TGetListRequest是一个结构,不应该有一个处理程序。