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文件,编译后文件自动存储位置为:

  .\boost_1_61_0\stage\     (windows下boost库的简单编译)

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

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

  下载Thrift压缩包(v0.9.3),解压进入\thrift-0.9.3\lib\cpp,使用 VS2010及以上打开Thrift.sln,有libthrift,libthriftnb两个工程。libthriftnb工程是非阻塞(non-blocking)模式的服务器,非阻塞模式需要依赖libevent库。检查所需的include路径和lib路径,编译完成后在\thrift-0.9.1\lib\cpp\Debug(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如下:

 namespace cpp calculate
service Calculator
{
i32 add(:i32 add_num1, :i32 add_num2),
i32 subtract(:i32 sub_num1, :i32 sub_num2)
}
 

  (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函数开始部分添加代码:

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

  (4)、编写客户端Client

 #include "Calculator.h"
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h> using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using boost::shared_ptr;
using namespace ::calculate;
int main(int argc, char **argv)
{
shared_ptr<TSocket> socket(new TSocket("127.0.0.1",));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
CalculatorClient client(protocol);
try
{
transport->open();
}
catch(TTransportException)
{
transport->close();
} int res_add = client.add(, );
printf("client.add(%d, %d) = %d\n", , , res_add);
int res_subtract = client.subtract(, );
printf("client.subtract(%d, %d) = %d\n", , , res_subtract);
transport->close(); getchar();
return ;
}

  注:无论是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编译时候出现的问题

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

C++库(Thrift)的更多相关文章

  1. Thrift原理与使用实例

    一 Thrift框架介绍 1 前言 Thrift是一个跨语言的服务部署框架,最初由Faceboo开发并进入Apache开源项目. Thrift特征如下: 1)Thrift有自己的跨机器通信框架,并提供 ...

  2. 【RPC】Thrift ICE 等 RPC 框架相关资料

    RPC框架-Thrift-ICE Apache Thrift - Documentation Apache Thrift - Index of tutorial/ Apache Thrift - Ab ...

  3. VS2017 Thrift编译出的Release版本的库调用报错LNK2001

    在使用thrift的过程中, 当我使用完thrift debug版本编译出来的库调试完成后, 改成release版本的时候, 就出现了如下错误, 莫名其妙啊, 同一套代码, 那只能是编译库的时候设置和 ...

  4. 记录Mac OS下编译Thrift库

    方法一:brew管理工具安装Homebrew是Mac开发包管理工具,类似于Linux的apt-get之类的,实它相当于开发软件界的 Appstore.借助该管理工具,可以自动化地安装软件包,它会自动安 ...

  5. 值得推荐的C/C++框架和库

    值得推荐的C/C++框架和库 [本文系外部转贴,原文地址:http://coolshell.info/c/c++/2014/12/13/c-open-project.htm]留作存档 下次造轮子前先看 ...

  6. thrift 服务端linux C ++ 与客户端 windows python 环境配置(thrift 自带tutorial为例)

    关于Thrift文档化的确是做的不好.摸索了很久才终于把跨linux与windows跨C++与python语言的配置成功完成.以下是步骤: 1)                 Linux下环境配置 ...

  7. thrift笔记

    Thrift tutorial 演示 python服务端与客户端本文的开发环境是windows 7 + python2.7.3Thrift官方主页:http://thrift.apache.org/先 ...

  8. [转载]C/C++框架和库

    C/C++框架和库 装载自:http://blog.csdn.net/xiaoxiaoyeyaya/article/details/42541419 值得学习的C语言开源项目 Webbench Web ...

  9. Thrift:Quick Start

    Thrift 快速开始 1 Thrift 介绍 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等.其中所用到的 ...

随机推荐

  1. InnerClass内部类

    1,内部类概述 定义:把A类定义在B类内部,则A类是内部类.如下所示: class Outer1{外部类 String name1; public void show(){ System.out.pr ...

  2. [整理]Android开发(一)环境安装

    所有相关下载均可通过http://www.androiddevtools.cn/下载 安装JAVA JDK 下载Windows x64 180.44 MB jdk-8u45-windows-x64.e ...

  3. 清北学堂模拟day6 兔子

    [问题描述] 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连.换句话讲,这些兔子 ...

  4. hdu.5211.Mutiple(数学推导 && 在logn的时间内求一个数的所有因子)

    Mutiple  Accepts: 476  Submissions: 1025  Time Limit: 4000/2000 MS (Java/Others)  Memory Limit: 6553 ...

  5. JAVA 笔记

    一.Java基础以及面向对象编程1.float类型的数自动转换成double类型时,可能会出现前后不相等的情况,因为有些数不能够用有限的二进制位精确表示.2.右移>>右移,左边空出位以符号 ...

  6. SpringBoot使用的心得记录

    security配置 import com.yineng.corpsysland.security.*; import com.yineng.corpsysland.web.filter.Author ...

  7. iOS开发——高级篇——Parse 教程:网络后台基础

    本教程已针对Swift, iOS 8.3, Xcode 6.3及最新的Parse SDK(1.7.1版本)更新. 网络后台支持可以为你的App添加许多崭新的功能:不论是数据同步,社交分享,还是云端存储 ...

  8. 手把手教你crontab排障

    导读 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,cr ...

  9. leetcode 215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  10. call(),apply()和bind()

    三个函数都是Function对象自带的三个方法,主要作用是改变函数中this的指向. call() 语法 fun.call(thisArg[, arg1[, arg2[, ...]]]) 该方法可以传 ...