thrift简介
thrift是一个用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎, 以构建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。
Thrift允许定义一个简单的定义文件中的数据类型和服务接口,以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
—–百度百科
thrift代码生成
在学习如何用thrift进行代码生成时,可以先去看看thrift的官方文档。
在这里,可以看到thrift支持下面这些类型:
基本类型
- bool:一个bool值(true或false)
- byte:一个8位有符号整数
- i16:一个16位有符号整数
- i32:一个32位有符号整数
- i64:一个64位浮点数
- double:一个64位浮点数
- string:使用UTF-8编码编码的字符串
- 特殊类型
- binary:一个未编码的字节队列(这是上面string的一种特殊形式,为了给java提供更好的互操作性而添加,目前计划以后将这个类型提僧到基本类型。)
- 结构体
- struct :定义一个共同的对象,它本质上等同于OOP语言中的类,但是没有继承。结构体具有一组强类型字段,每个字段都有唯一的名称标识符。字段可能有Thrift IDL中描述的各种注释(数字字段ID,可选的默认值等)
- 容器
thrift的容器是强类型的容器,能够映射到大多数编程语言中 常用的容器类型。
- list:元素的有序列表。相当于C#里面的List< T>
- set:无序但唯一的一组元素。相当于C#里面的THashSet< T>
- map:一个严格键唯一的键值对集合。相当于C#里面的Dictionary< T1, T2>
- 异常
- exception:异常在功能上等同于结构,除了它们在每种目标编程语言中适当地继承本机异常基类以便与任何给定语言中的本地异常处理无缝集成。
- 服务
- service:服务的定义在语义上等同于在面向对象编程中定义接口(或纯虚拟抽象类)。Thrift编译器生成实现该接口的功能齐全的客户端和服务器存根。
一个服务由一组命名函数组成,每个函数都有一个参数列表和一个返回类型。
请注意,除了所有其他定义的Thrift类型之外,void是函数返回的有效类型。此外,使用oneway修饰的void返回值函数将生成不等待响应的代码。请注意,被void修饰的函数将返回一个响应到客户端,保证在服务器端的操作已经完成。使用oneway方法调用服务将只能保证请求在传输层成功。同一客户端的oneway方法调用可以由服务器并行/不按顺序执行。
- service:服务的定义在语义上等同于在面向对象编程中定义接口(或纯虚拟抽象类)。Thrift编译器生成实现该接口的功能齐全的客户端和服务器存根。
下面列举一个简单的thrift文件实例:
namespace csharp DemoService.Interface
struct Demo
{
1:i32 Id,
2:map<string,string> parm1,
3:set<string> parm2,
}
service DemoService
{
bool AddDemo(1:Demo demo)//增加
bool DeleteDemo(1:list<i32> id)//删除
bool UpdateDemo(1:Demo demo)//修改
Demo GetDemoById(1:i32 id)//根据Id查询
list<Demo> GetAllDemo()//查询所有
}
打开cmd窗口,将路径切换到thrift.exe的路径下,并将上面的文件保存到一个新建的txt文档中,修改后缀名为.thrift。官网下载路径为:thrift官网下载
运行下面命令:
thrift.exe -gen csharp demo.thrift(自己保存的文件名)
就会在该目录下生成一个gen-csharp的文件夹,里面会有一个DemoService的文件夹,里面会有一个Inteface文件夹(这2个文件夹根据namespace后面的名称生成)。里面会有2个文件:Demo.cs、DemoService.cs。
里面分别对应了struct和service之后的内容。
Demo.cs简要内容:
DemoService.cs简要内容:
通过上面的内容,可以看到map< string,string>将会转换成Dictionary< string, string>,set< string>将转换成THashSet< string>,在DemoService中,将生成一个包含了thrift文件标识的函数接口。这2个文件将服务端和客户端通信的关键。在服务端,需要继承这个接口,并实现接口中的函数。在客户端实例化DemoService中的Client,在Client类中也会有接口中方法的实现(就不具体展开了,有兴趣的可以自行查看DemoService的具体内容,还有很多远程调用的协议之类的说明。),然后调用client里面的方法,就可以调用到服务端的方法了。
thrift客户端与服务端创建(C#)
服务端
服务端服务启动代码:
static void StartService()
{
try
{
//设置服务端口为8080
TServerSocket serverTransport = new TServerSocket(8080);
//设置传输协议工厂
TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();
//关联处理器与服务的实现
TProcessor processor = new DemoService.Processor(new DemoAchieveService());
//创建服务端对象
TServer server = new TThreadPoolServer(processor, serverTransport, new TTransportFactory(), factory);
Console.WriteLine("服务端正在监听8080端口");
server.Serve();
}
catch (TTransportException ex)
{
Console.WriteLine(ex.Message);
}
}
服务端还需要实现一个具体的类,上面代码中的DemoAchieveService类,这个类需要继承自DemoService.Iface,并且实现接口里面的方法,具体内容就展示了。
客户端
客户端创建Client代码:
/// <summary>
/// 创建客户端
/// </summary>
/// <returns></returns>
public DemoService.Client CreateClient()
{
try
{
//设置服务端端口号和地址
TTransport transport = new TSocket("127.0.0.1", 8080);
transport.Open();
//设置传输协议为二进制传输协议
TProtocol protocol = new TBinaryProtocol(transport);
//创建客户端对象
DemoService.Client client = new DemoService.Client(protocol);
return client;
}
catch (Exception ex)
{
throw;
}
}
创建好Client后,通过client调用方法就可以了。