thrift --gen  csharp  search.thrift

thrift --gen java search.thrift

Thrift是facebook的一个技术核心框架,07年四月开放源码,08年5月进入apache孵化器。

简言之,开发者可以通过写一个.thrift文件,定义相应的数据结构和服务接口,该thrift文件会由Thrift相应的解释器解释生成指定的类型(C++,java等等)代码,然后用户在客户端和服务器端,分别在生成的代码里编写相应的服务接口函数,并做相应配置选择,就可以实现跨平台的rpc调用。

这里给出一个使用的简单例子,之中牵扯到了一些编译方面的细节问题。

定义数据结构的.thrift文件book.thrift:

//book.thrift
namespace cpp example
struct Book_Info {
1: i32 book_id,
2: string book_name,
3: string book_author,
4: double book_price,
5: string book_publisher,
}

定义rpc服务接口的rpc.thrift文件,定义了service类:

//rpc.thrift
namespace cpp example
include "book.thrift"
service BookServlet {
bool Sender(1: list<book.Book_Info> books);
oneway void Sender2(1: list<book.Book_Info> books);
}

调用thrift的编译器,将上面的两个thrift文件转化为对应语言的代码,这里我选了C++:

thrift --gen cpp book.thrift
thrift --gen cpp rpc.thrift

然后会在当前目录下生成一个./gen-cpp文件夹,该文件夹里就是生成的相应的cpp文件,所生成的文件有以下几类[1]:

对应的,对于本例,所生成的文件列表如下:

其中的makefile不是thrift生成的文件,是我编译用的,主要关注其他文件。这个gen-cpp的文件客户端和服务器端都需要。

服务器端:

修改BookServlet_server.skeleton.cpp,作为服务器端服务响应:

// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it. #include "BookServlet.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 namespace ::apache::thrift::server; using boost::shared_ptr; using namespace ::example; class BookServletHandler : virtual public BookServletIf {
public:
BookServletHandler() {
// Your initialization goes here
} bool Sender(const std::vector< ::example::Book_Info> & books) {
// Your implementation goes here
std::vector< ::example::Book_Info>::const_iterator iter;
for(iter=books.begin();iter!=books.end();iter++) {
printf("books size: %d\n",books.size());
printf("send 1: %d, %s, %s\n",(*iter).book_id,(*iter).book_name.c_str(),(*iter).book_author.c_str());
}
return true;
} void Sender2(const std::vector< ::example::Book_Info> & books) {
// Your implementation goes here
std::vector< ::example::Book_Info>::const_iterator iter;
for(iter=books.begin();iter!=books.end();iter++) {
printf("books size: %d\n",books.size());
printf("send 2: %d, %s, %s\n",(*iter).book_id,(*iter).book_name.c_str(),(*iter).book_author.c_str());
}
} }; int main(int argc, char **argv) {
int port = 9090;
shared_ptr<BookServletHandler> handler(new BookServletHandler());
shared_ptr<TProcessor> processor(new BookServletProcessor(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;
}

监听端口9090,所做的事情其实就是将client传递过来的books参数的内容打印出来,来验证是否实现了数据传递。然后在服务器端用g++编译,thrift编译有点儿恶,一方面需要将各种库(boost,thrift等)加进来,另一方面有时候还会有一些uint_32没有定义什么的错误,还要加一些编译参数,如下给出一个可以编译通过的makefile模板,大家可以根据自己机器的程序路径和文件名做相应修改。thrift生成代码编译的makefile模板:

BOOST_DIR = /usr/include/boost
THRIFT_DIR = /usr/local/include/thrift/
LIB_DIR = /usr/local/lib
GEN_SRC = ./book_types.cpp ./rpc_types.cpp ./BookServlet.cpp ./book_constants.cpp ./rpc_constants.cpp
default: server
server: BookServlet_server.skeleton.cpp
g++ -DHAVE_NETINET_IN_H -DHAVE_INTTYPES_H -o CppServer -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift BookServlet_server.skeleton.cpp ${GEN_SRC}
clean:
$(RM) -r CppServer

编译通过后就在服务器端运行响应的程序./CppServer

 客户端

客户端代码,thrift_cli.cpp,同样放在./gen-cpp文件夹下:

#include "BookServlet.h"
#include "book_types.h"
#include <protocol/TBinaryProtocol.h> #include <transport/TSocket.h> #include <transport/TBufferTransports.h> #include <vector> using namespace std; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using boost::shared_ptr; using namespace example; //other headers, using namespace int main(int argc, char** argv) { shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); shared_ptr<TTransport> transport(new TBufferedTransport(socket)); shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); example::BookServletClient client(protocol); try { transport->open(); vector<example::Book_Info> books; Book_Info ibook;
ibook.book_id = 1324;
ibook.book_name = "thrift";
ibook.book_price = 22;
ibook.book_publisher = "letv";
ibook.book_author = "luis";
books.push_back(ibook); ibook.book_id = 1024;
books.push_back(ibook); client.Sender(books);
client.Sender2(books); transport->close(); } catch (TException &tx) { printf("iERRORs %s\n", tx.what()); } }

由于我的服务器和客户端实在同一台机器上测的,所以访问localhost,这个客户端程序其实就是向books里加了两个数据,然后client.Sender()和client.Sender2()调用服务器端对应的函数。同样使用上面的makefile文件(修改一下文件名称)进行编译,然后运行./thrift_cli。

运行结果

服务器端接到请求,将客户端传递过来的数据对象books打印了出来,证明rpc成功:

本文只是给了一个thrift简单能够run起来的应用示例,部分参考了[1]和[2],如果要深入地使用thrift,了解thrift的内部架构和实现就是必须的了。

Thrift初用小结的更多相关文章

  1. Django3.0 异步通信初体验(小结)

    2019年12月2日,Django终于正式发布了3.0版本.怀着无比的期待,我们来尝试一下吧! (附ASGI官方文档地址:https://asgi.readthedocs.io/en/latest/e ...

  2. [thrift] thrift基本原理及使用

    参考文章RPC 基本原理与 Apach Thrift 初体验 RPC基本原理 RPC(Remote Procedure Call),远程过程调用,大部分的RPC框架都遵循如下三个开发步骤: 1. 定义 ...

  3. Thrift-java学习小结

    ➠更多技术干货请戳:听云博客 Thrift是什么?什么情况下使用thrift Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基金会将Thrift作为一个开 ...

  4. thrift之初体验

    hrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, ...

  5. RPC框架基础概念理解以及使用初体验

    RPC:Remote Procedure Call(远程服务调用) RPC是做什么的 通过RPC框架机器A某个进程可以通过网络调用机器B上的进程方法,就像在本地上调用一样. RPC可以基于HTTP或者 ...

  6. WWDC15 Session笔记 - Xcode 7 UI 测试初窥

    https://onevcat.com/2015/09/ui-testing/ WWDC15 Session笔记 - Xcode 7 UI 测试初窥 Unit Test 在 iOS 开发中已经有足够多 ...

  7. Thrift 个人实战--初次体验Thrift

    前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...

  8. Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  9. OC小结

    #import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * a ...

随机推荐

  1. 【BZOJ2038】【莫队】小z的袜子

    Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...

  2. javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

    大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...

  3. HTML5中的Range对象的研究(转载)

    一:Range对象的概念 Range对象代表页面上的一段连续区域,通过Range对象,可以获取或修改页面上的任何区域,可以通过如下创建一个空的Range对象,如下: var  range = docu ...

  4. 最新发布C#.NET快速开发框架企业版V4.0 (适合开发ERP、进销存系统)

    C/S系统开发框架-企业版 V4.0 (Enterprise Edition) http://www.csframework.com/cs-framework-4.0.htm 视频下载: 百度网盘: ...

  5. python【第九篇】多线程、多进程

    内容提要 paramiko模块 进程.与线程区别 python GIL全局解释器锁 多线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...

  6. python与编码方式

    1.编码方式: ASCII编码:用来表示英文,它使用1个字节表示,其中第一位规定为0,其他7位存储数据,一共可以表示128个字符. 拓展ASCII编码:用于表示更多的欧洲文字,用8个位存储数据,一共可 ...

  7. Python Tutorial 学习(三)--An Informal Introduction to Python

    3.1. 将Python用作计算器 3.1.1. Numbers 数 作为一个计算器,python支持简单的操作, '+','-','*','/'地球人都知道的加减乘除. ()可以用来改变优先级,同数 ...

  8. 一个CS出身的基本素养

    从前天10号提交Paper之后,连三个晚上之后突然正常起来竟然变成倒时差状态. 这周打算给自己一个空窗期,好好想想下两到三个月要做的事. 好吧,除了"一日一算法",当下两个月还有一 ...

  9. 在Adobe Reader中保存PDF表单数据的方法

    通常,Adobe Reader 用户填写表单后,是无法保存所填表单的副本的.但是,对于 Reader 8 和更高版本的用户,您可以扩展其权限,使他们可以完成此操作.如果您使用的是 Acrobat Pr ...

  10. 离散傅里叶变换(DFT)

    目录     一.研究的意义     二.DFT的定义    三.DFT与傅里叶变换和Z变换的关系     四.DFT的周期性     五.matlab实验       五.1 程序         ...