Thrift框架学习
参考文章:1、http://www.kankanews.com/ICkengine/archives/54084.shtml
2、http://www.cnblogs.com/liping13599168/archive/2011/09/15/2176836.html
Golang内置了对RPC支持,但只能适用于go语言程序之间调用。Thrift是一种可伸缩的跨语言服务框架,它支持C++,C#,Java,Python,Go等多种语言。
thrift允许你定义一个简单的定义文件中的数据类型和服务接口,以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
这种方式与微软的WCF框架以及Android中的AIDL服务的做法很类似。
1、安装Go语言的thrift包
参考文章1给出的地址是:go get git.apache.org/thrift.git/lib/go/thrift,但该地址现在似乎不能访问了,请使用下面的命令:
go get github.com/apache/thrift/lib/go/thrift
2、下载脚本编译器
下载地址:http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.1/thrift-0.9.1.exe
该编译工具可将thrift脚本文件编译为目标变成语言代码。
3、创建脚本
脚本文件采用thrift自带教程github.com\apache\thrift\tutorial中的shared.thrift和tutorial.thrift:
shared.thrift文件如下:
namespace go shared
struct SharedStruct {
1: i32 key
2: string value
}
service SharedService {
SharedStruct getStruct(1: i32 key)
}
tutorial.thrift文件如下:
include "shared.thrift"
namespace go tutorial
typedef i32 MyInteger
const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
enum Operation {
ADD = 1,
SUBTRACT = 2,
MULTIPLY = 3,
DIVIDE = 4
}
struct Work {
1: i32 num1 = 0,
2: i32 num2,
3: Operation op,
4: optional string comment,
}
exception InvalidOperation {
1: i32 what,
2: string why
}
service Calculator extends shared.SharedService {
void ping(),
i32 add(1:i32 num1, 2:i32 num2),
i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
oneway void zip()
}
4、编译脚本
分别执行 thrift -gen go x:\shared.thrift和thrift -gen go x:\tutorial.thrift 命令,参数go表示生成go代码,可以根据实际情况使用csharp,java,python等参数。
5、示例代码
下面我们使用C#语言实现的客户端与Go语言实现的服务端通信,进行跨语言调用。
将第4步中生成的go代码放到服务端目录下,服务端代码如下:
main.go文件
package main
import (
"crypto/tls"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
"tutorial"
)
func main() {
protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
transportFactory := thrift.NewTTransportFactory()
addr := "localhost:9090"
secure := false
if err := runServer(transportFactory, protocolFactory, addr, secure); err != nil {
fmt.Println("error running server:", err)
}
}
func runServer(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory, addr string, secure bool) error {
var transport thrift.TServerTransport
var err error
if secure {
cfg := new(tls.Config)
if cert, err := tls.LoadX509KeyPair("server.crt", "server.key"); err == nil {
cfg.Certificates = append(cfg.Certificates, cert)
} else {
return err
}
transport, err = thrift.NewTSSLServerSocket(addr, cfg)
} else {
transport, err = thrift.NewTServerSocket(addr)
}
if err != nil {
return err
}
fmt.Printf("%T\n", transport)
handler := NewCalculatorHandler()
processor := tutorial.NewCalculatorProcessor(handler)
server := thrift.NewTSimpleServer4(processor, transport, transportFactory, protocolFactory)
fmt.Println("Starting the simple server... on ", addr)
return server.Serve()
}
handler.go文件使用原文件。
将第4步生成的c#代码加入客户端工程,并引用thrift.dll(该组件的代码可在..\github.com\apache\thrift\tutorial\csharp下找到),如图所示:

客户端测试代码如下:
class Program
{
static void Main(string[] args)
{
try
{
TTransport transport = new TSocket("localhost", );
TProtocol protocol = new TBinaryProtocol(transport);
Calculator.Client client = new Calculator.Client(protocol); transport.Open();
try
{
client.ping();
Console.WriteLine("ping()"); int sum = client.add(, );
Console.WriteLine("1+1={0}", sum); Work work = new Work(); work.Op = Operation.DIVIDE;
work.Num1 = ;
work.Num2 = ;
try
{
int quotient = client.calculate(, work);
Console.WriteLine("Whoa we can divide by 0");
}
catch (InvalidOperation io)
{
Console.WriteLine("Invalid operation: " + io.Why);
} work.Op = Operation.SUBTRACT;
work.Num1 = ;
work.Num2 = ;
try
{
int diff = client.calculate(, work);
Console.WriteLine("15-10={0}", diff);
}
catch (InvalidOperation io)
{
Console.WriteLine("Invalid operation: " + io.Why);
} SharedStruct log = client.getStruct();
Console.WriteLine("Check log: {0}", log.Value); }
finally
{
transport.Close();
}
}
catch (TApplicationException x)
{
Console.WriteLine(x.StackTrace);
}
Console.ReadKey();
}
}
测试结果:

本文结束。源码下载:thriftserver thriftclient
Thrift框架学习的更多相关文章
- thrift框架总结,可伸缩的跨语言服务开发框架
thrift框架总结,可伸缩的跨语言服务开发框架 前言: 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等.其 ...
- IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API
IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习之保护API. 使用IdentityServer4 来实现使用客户端凭据保护ASP.N ...
- Hadoop学习笔记—18.Sqoop框架学习
一.Sqoop基础:连接关系型数据库与Hadoop的桥梁 1.1 Sqoop的基本概念 Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据移植过去并不容易.Apache Sqoop正在加 ...
- Spring框架学习一
Spring框架学习,转自http://blog.csdn.net/lishuangzhe7047/article/details/20740209 Spring框架学习(一) 1.什么是Spring ...
- EF框架学习手记
转载: [ASP.NET MVC]: - EF框架学习手记 1.EF(Entity Framework)实体框架EF是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架 ...
- web框架学习列表
转载自鲁塔弗的博客,原文网址:http://lutaf.com/148.htm web framework层出不穷,特别是ruby/python,各有10+个,php/java也是一大堆 根据我自己的 ...
- 2013 最新的 play web framework 版本 1.2.3 框架学习文档整理
Play framework框架学习文档 Play framework框架学习文档 1 一.什么是Playframework 3 二.playframework框架的优点 4 三.Play Frame ...
- SSH 框架学习之初识Java中的Action、Dao、Service、Model-收藏
SSH 框架学习之初识Java中的Action.Dao.Service.Model-----------------------------学到就要查,自己动手动脑!!! 基础知识目前不够,有感性 ...
- 各种demo——CI框架学习
各种demo——CI框架学习 寒假学习一下CI框架,请各位多多指教! 一.CI的HelloWorld! 注意:CI禁止直接通过文件目录来访问控制器. ./application/controlle ...
随机推荐
- SlidingMenu Demo
参考:http://www.krislq.com/2013/03/android_case_slidingmenu_fragment/ 我下载了它的例子,然后自己重写了一下,运行时总报错,原来是sup ...
- 03-23 MVC框架(以查询、删除为例)
1.MVC的定义: MVC(Model-View-Controller,模型-视图-控制器)是用于将应用程序粉好吃呢过如下3个主要方面的体系结构模式: 模型(Model):一组类和业务规则,类用于描述 ...
- 使用ssh client与bash scripts轻松管理多台主机
当我们需要控制一个局域网中的很多台服务器时,一个简单的全局操作可能会被放大地异常繁琐,这时我们就会需要新的工具来快速完成这种工作. 我们将使用ssh客户端提供的一些工具来快速完成这一开发工作,我们的开 ...
- 在kindeditor 获取textarea 中 输入的值
要在kindeditor 获取textarea 中 输入的值 必须在kindeditor创建的时候添加下面红色字体的代码 kindeditor创建代码如下: var editor;KindEd ...
- CentOS6上安装Flash Player
Linux CentOS6服务器中的某个需要远程操作的项目需要使用到Adobe Flash Player组件,直接通过YUM方式安装不了,于是通过强大的搜索,还是可以解决到安装方法的,通过重新加载安装 ...
- LVM 逻辑卷管理
简介: LVM ( Logical Volume Manager ) 逻辑卷管理 一.创建 LV 1.首先在你的虚拟机上添加一块新的硬盘用来做实验. 2.安装 lvm : yum -y install ...
- BUI 框架使用指南
指南说明:只适用于对框架的剥离 如果不需要剥离则原来的东西直接粘贴就行 在主界面中使用时需要加入一下引用bui.js jquery.js config.js 末尾的文件 BUI.use(位置1, fu ...
- 转 sql注入
1.判断有无注入点 ; and 1=1 and 1=2 2.猜表一般的表的名称无非是admin adminuser user pass password 等.. and 0<>(selec ...
- 高性能Web服务器Nginx的配置与部署研究(7)核心模块之主模块的非测试常用指令
1. error_log 含义:指定存储错误日志的文件 语法:error_log <file> [debug|info|notice|warn|error|crit] 缺省:${prefi ...
- python中函数作用域
在python中,一个函数就是一个作用域 name = 'xiaoyafei' def change_name(): name = 'sthu' print('在change_name里的name:' ...