HelloWorld by Thrift

来源:互联网 发布:淘宝千人千面好用吗 编辑:程序博客网 时间:2024/06/05 08:59

Thrift 是什么

The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

from : http://thrift.apache.org/
翻译:
Apache Thrift 是一个可扩展的用来实现跨语言服务的开发框架。
它组合一个代码生成引擎和一个软件栈来创建下面各种语言 (C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi 。。。 )之间的高效无缝的服务。


Thrift 的安装

环境 : OpenSUSE , 64bit
参见:

http://thrift.apache.org/docs/BuildingFromSource

  1. 下载源码zip并解压。
  2. 于Thrift根目录执行 ./configure
  3. 于Thrift根目录执行 ./make

期间遇到提示某库(比如 libevent) 没有装好, 就使用zypper(类似Ubuntu 的apt-get) 默认安装 .
在编译test的时候遇到Makefile的问题, gen-cpp 内头文件无法include, 就是用thrift 命令手动生成之( 或者先删除对应Makefile命令 , 木有关系) 。

Thrift 的基本概念

参见

http://thrift.apache.org/docs/concepts

软件栈概念图:

  +-------------------------------------------+  | Server                                    |  | (single-threaded, event-driven etc)       |  +-------------------------------------------+  | Processor                                 |  | (compiler generated)                      |  +-------------------------------------------+  | Protocol                                  |  | (JSON, compact etc)                       |  +-------------------------------------------+  | Transport                                 |  | (raw TCP, HTTP etc)                       |  +-------------------------------------------+

实际是Thrift 是采用RPC(远程调用) 的概念实现跨语言的, Transport层负责使用指定协议(TCP / HTTP / FILE / PIPE … ) 交换数据, Protocol 层负责用指定的协议( JSON ,Binary , XML … ) 编解码数据, Processor 层是我们自己code的层, 负责 接口的具体实现( server端 ) / 对接口的调用使用 ( client 端) 。 Server 层实际是是对下面3层的整合, 当 client 连接到server调用某个接口的时候, Processor 按照接口规定准备数据, Protocol 按照配置编码数据, 通过Transport 层按照指定的协议发送数据, server 通过Transport收到数据后, Protocol 解码数据, Processor 层使用数据真正的调用接口,完成逻辑, 如果有返回值的话, 再按照相反的流程传回client 。 见下图 :
Thrift远程调用的数据栈


使用Thrift 写HelloWorld

Thrift 除了 Processor 的实现和server的配置之外, 其他的代码都会给自动生。
首先, 我们要定义接口 , 使用 Thrift 定义的自己的IDL ( interface description language ) ,

hello.thrift

service Hello {  string getString()}

我的服务器端使用C++ , 所以先生成对应的C++代码 :

thrift --gen cpp hello.thrift

自动生成gen-cpp 文件夹, 打开里面的hello.h 头文件, 找到下面的接口 :

class HelloIf { public:  virtual ~HelloIf() {}  virtual void getString(std::string& _return) = 0;};

为服务器接口添加实现代码 helloServer.cpp ( 由生成的 Hello_server.skeleton.cpp 修改成):

#include <thrift/concurrency/ThreadManager.h>#include <thrift/concurrency/PosixThreadFactory.h>#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/server/TSimpleServer.h>#include <thrift/server/TThreadPoolServer.h>#include <thrift/server/TThreadedServer.h>#include <thrift/transport/TServerSocket.h>#include <thrift/transport/TTransportUtils.h>#include <thrift/TToString.h>#include <iostream>#include <stdexcept>#include <sstream>#include "gen-cpp/Hello.h"using namespace std;using namespace apache::thrift;using namespace apache::thrift::concurrency;using namespace apache::thrift::protocol;using namespace apache::thrift::transport;using namespace apache::thrift::server;class HelloHandler : public HelloIf{    public:        virtual void getString(string& _return) {            _return = "Hello World\n";    }};int main(int argc, char **argv) {  boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());  boost::shared_ptr<HelloHandler> handler(new HelloHandler());  boost::shared_ptr<TProcessor> processor(new HelloProcessor(handler));  boost::shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090));  boost::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());  TSimpleServer server(processor,                       serverTransport,                       transportFactory,                       protocolFactory);  cout << "Starting the server..." << endl;  server.serve();  cout << "Done." << endl;  return 0;}

客户端也C++语言 ( 好吧我最熟悉这个)

#include <iostream>#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/transport/TSocket.h>#include <thrift/transport/TTransportUtils.h>#include "gen-cpp/Hello.h"using namespace std;using namespace apache::thrift;using namespace apache::thrift::protocol;using namespace apache::thrift::transport;int main(int argc, char** argv) {  boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));  boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));  boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));  HelloClient client(protocol);  transport->open();  string hello;  client.getString(hello);  cout<<hello;  transport->close();}

Cmake 维护工程 :

cmake_minimum_required(VERSION 3.0)PROJECT (helloWord)INCLUDE_DIRECTORIES(./gen-cpp)SET( SERVER_FILES helloServer.cpp)SET( LIB_SOURCE  ./gen-cpp/Hello.cpp ./gen-cpp/hello_constants.cpp ./gen-cpp/hello_types.cpp )ADD_EXECUTABLE(server  ${SERVER_FILES} ${LIB_SOURCE} ) TARGET_LINK_LIBRARIES(server -lthrift)  

编译 :

mkdir build
cd build
cmake ,,
make


先启动server , 然后启动client 输出 :

Hello World


0 0
原创粉丝点击