zoukankan      html  css  js  c++  java
  • C++库(Thrift)

    Thrift通信框架

    0 简介

      Thrift是一个软件通讯框架,用来进行可扩展且跨语言的服务的开发,最初由Facebook于2007年开发,2008年进入Apache开源项目。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C, C++, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, C++Script, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。thrift允许你定义一个简单的定义文件中的数据类型和服务接口,作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

    1 Thrift的安装(Windows/C++)

      Thrift需要用到几个开源库:

      1) Boost (http://www.boost.org/)

      Boost库是一个经过千锤百炼、可移植、开源的C++库,作为C++标准库的后备,是C++标准化进程的发动机之一,是不折不扣的“准”标准库,大部分Boost库的使用只需要包含头文件即可,少数需要链接库。其中几个比较有名气的库为Regex正则表达式库、Thread可移植的C++多线程库、Pool内存池管理库、smart_ptr智能指针库等。

      2) Libevent (http://libevent.org/

      Libevent是一个由C语言编写的、轻量级的开源高性能网络库,主要特点:事件驱动、高性能、轻量级、专注于网络、跨平台等。

       首先编译boost和libevent生成对应的lib文件,编译后文件自动存储位置为:

      .oost_1_61_0stage     (windows下boost库的简单编译)

      .libeventlibevent-2.0.21-stable  (windows下编译及使用libevent)

      3) 下载、安装libthrift (https://thrift.apache.org)

      下载Thrift压缩包(v0.9.3),解压进入 hrift-0.9.3libcpp,使用 VS2010及以上打开Thrift.sln,有libthrift,libthriftnb两个工程。libthriftnb工程是非阻塞(non-blocking)模式的服务器,非阻塞模式需要依赖libevent库。检查所需的include路径和lib路径,编译完成后在 hrift-0.9.1libcppDebug(Release)中生成libthrift.lib和libthriftnb.lib。

    2 Thrift基础

      (1)数据类型

      基本类型

        bool:布尔值,true 或 false,对应 C++ 的 bool

        byte:8 位有符号整数,对应 C++ 的 byte

        i16:16 位有符号整数,对应 C++ 的 short

        i32:32 位有符号整数,对应 C++ 的 int

        i64:64 位有符号整数,对应 C++ 的 long

        double:64 位浮点数,对应 C++ 的 double

        string:utf-8编码的字符串,对应 C++ 的 string

      结构体类型

        struct:定义公共的对象,类似于 C 语言中的结构体定义

      容器类型

        list:对应 C++ 的 list

        set:对应 C++ 的 set

        map:对应 C++ 的map

      异常类型

        exception:对应 C++ 的 Exception

      服务类型

        service:对应服务的类

      (2)通讯支持

       支持的数据传输协议(传输格式)

          TBinaryProtocol : 二进制格式.

          TCompactProtocol : 压缩格式

          TJSONProtocol : JSON格式

          TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

          tips: 客户端和服务端的协议要一致

      支持的数据传输方式

        TSocket -阻塞式socker

        TFramedTransport–以frame为单位进行传输,非阻塞式服务中使用。

        TFileTransport – 以文件形式进行传输。

        TMemoryTransport –将内存用于I/O. java实现时使用了简单的ByteArrayOutputStream。

        TZlibTransport – 使用zlib进行压缩, 与其他传输方式联合使用。当前无java实现。

       支持的服务模型

        TSimpleServer – 简单的单线程服务模型,常用于测试教学使用

        TThreadPoolServer – 多线程服务模型,使用标准的阻塞式IO。

        TNonblockingServer – 多线程服务模型,使用非阻塞式IO(需使用TFramedTransport数据传输方式)

    3 一个例子

      (1)、编写idl文件

      编写calculate.idl如下:

    1 namespace cpp calculate
    2 service Calculator
    3 {
    4     i32 add(1:i32 add_num1, 2:i32 add_num2),
    5     i32 subtract(1:i32 sub_num1, 2:i32 sub_num2)
    6 }
     

      (2)、编译生成框架文件(C++)

     

      Thrift由两部分组成:编译器(在compiler目录下,采用C++编写)和服务器(在lib目录下),其中编译器的作用是将用户定义的thrift文件编译生成对应语言的代码,而服务器是事先已经实现好的、可供用户直接使用的RPC Server(当然,用户也很容易编写自己的server)。

      在idl文件所在路径打开cmd,输入:thrift-0.9.3.exe --gen cpp calculate.idl

      结果代码存放在gen-cpp目录下,其中的文件说明:

          calculate_constants:idl文件中一些常量的定义

          calculate_types:idl文件中定义的数据类型

          Calculator:idl文件中定义的服务

      Calculator_server.skeleton:给出一个Server端代码框架

      (3)、编写服务端Server

           将Calculator_server.skeleton.cpp内容拷贝,并在main函数开始部分添加代码:

      1  TWinsockSigleton::create(); //高版本不再需要
      2  int port = 9090;
     

      (4)、编写客户端Client

     1 #include "Calculator.h"
     2 #include <thrift/transport/TSocket.h>
     3 #include <thrift/transport/TBufferTransports.h>
     4 #include <thrift/protocol/TBinaryProtocol.h>
     5 #include <thrift/server/TSimpleServer.h>
     6 #include <thrift/transport/TServerSocket.h>
     7 #include <thrift/transport/TBufferTransports.h>
     8 
     9 using namespace apache::thrift;
    10 using namespace apache::thrift::protocol;
    11 using namespace apache::thrift::transport;
    12 using boost::shared_ptr;
    13 using namespace  ::calculate;
    14 int main(int argc, char **argv)
    15 {
    16     shared_ptr<TSocket> socket(new TSocket("127.0.0.1",9090));
    17     shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    18     shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    19     CalculatorClient client(protocol);
    20     try
    21     {
    22         transport->open();
    23     }
    24     catch(TTransportException)
    25     {
    26         transport->close();
    27     }
    28 
    29     int res_add = client.add(1, 2);
    30     printf("client.add(%d, %d) = %d
    ", 1, 2, res_add);
    31     int res_subtract = client.subtract(3, 2);
    32     printf("client.subtract(%d, %d) = %d
    ", 3, 2, res_subtract);
    33     transport->close();
    34 
    35     getchar();
    36     return 0;
    37 }

      注:无论是Client还是Server,都必须包含必要的头文件和链接所需要的静态库文件。

      包含目录:工程配置页,C/C++ -> General -> Additional  Include Directories

      库目录:工程配置页,Linker -> General -> Additional  Library Directories,并在Input -> Additional Dependencies加入lib

      除此之外,还需要OpenSSL的包含路径和库路径,安装后指定即可。

       通过上面的例子分析可以看出,Thrift最重要的组件是编译器(采用C++编写),它为用户生成了网络通信相关的代码,从而大大减少了用户的编码工作。

      Thrift采用了C/S模型,不支持双向通信:client只能远程调用server端的RPC接口,但client端则没有RPC供server端调用,这意味着,client端能够主动与server端通信,但server端不能主动与client端通信而只能被动地对client端的请求作出应答。这种RPC模式在某些应用中存在缺陷,比如:有些应用,在大部分情况下,client端会主动向server端发请求或者向server端发送数据,而在少部分情况下,server端也需要主动向client发送一些命令,告知进行某些操作。为了解决该问题,通常使用双client/server,通信双方都既是client,也是server。该方案需要在通信双方之间建立两个通信通道,开启两个端口,这比较繁琐,且很不优雅。但仍是目前普遍采用的一套方案。

     

    相关资料

      l  Apache Thrift 在Windows下的安装与开发

      l  董的博客Thirft框架介绍

      l  董的博客Thrift使用指南

      l  董的博客使用Thrift RPC编写程序

      l  董的博客浅谈Thrift内部实现原理

      l  Thrift: Scalable Cross-Language Services Implementation

      PS: 

      CSDN提问:有没有人在windows下,用VS2010成功运行过thrift的程序?

      CSDN下载:解决在thrift0.9.3 cpp lib编译时候出现的问题

      需要例子源码的可给我留言~

  • 相关阅读:
    .Net转Java自学之路—Spring框架篇二(IOC注解、AOP)
    .Net转Java自学之路—Spring框架篇一(IOC入门)
    深入浅出ES6(七):箭头函数 Arrow Functions
    深入浅出ES6(六):解构 Destructuring
    深入浅出ES6(五):不定参数和默认参数
    深入浅出ES6(四):模板字符串
    深入浅出ES6(三):生成器 Generators
    深入浅出ES6(二):迭代器和for-of循环
    深入浅出ES6(一):ES6是什么
    父子页面之间跨域通信的方法
  • 原文地址:https://www.cnblogs.com/MakeView660/p/6043979.html
Copyright © 2011-2022 走看看