关闭

HelloWorld by Thrift

标签: helloworld
185人阅读 评论(0) 收藏 举报
分类:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:65142次
    • 积分:1592
    • 等级:
    • 排名:千里之外
    • 原创:79篇
    • 转载:13篇
    • 译文:3篇
    • 评论:13条
    最新评论