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 ...
随机推荐
- Python实践练习目录
缘由 做中学才是最好的方法,通过这些项目来加强自己的Python掌握程度. 原则 成体系地学,不搞"题海战术" 通所有不如精一物,精一物方可通所有 走心学,忌浮躁 项目列表 字符串 ...
- vue之slot,组件标签嵌套
vue之slot,组件标签嵌套 插槽(Slot),在各种vue的ui插件中,经常见到的多个组件标签相互嵌套(如下)就是以此为基础的. <el-col > <el-checkbox & ...
- 【302】C# TreeView 控件使用说明
参考:C# 中treeview 树节点图标的动态加载,及选中时图标改变 参考:C# TreeView 控件的综合使用方法 参考:TreeView 类 参考:TreeNode 类 1. 添加根和子级 通 ...
- PHP - 模拟HTTP请求, stream_context_create 和 fopen 和 fsockopen
一.fsocketopen,使用这个的过程看起来更像别的语言的socket编程 public function send($request) { /* 请求数据 */ $post_data = $re ...
- nextcloud 安装
nextcloud 优化 设置php.ini vim /etc/php/7.0/apache2/php.ini 添加以下代码: opcache.enable= opcache.enable_cli= ...
- keepalived之vrrp_script详解
通常情况下,利用keepalived做热备,其中一台设置为master,一台设置为backup.当master出现异常后,backup自动切换为master.当backup成为master后,mast ...
- 解剖Nginx·自动脚本篇(3)源码相关变量脚本 auto/sources
在configure脚本中,运行完auto/options和auto/init脚本后,接下来就运行auto/soures脚本.这个脚本是为编译做准备的. 目录 核心模块 事件模块 OpenSSL 模块 ...
- 104. Maximum Depth of Binary Tree (Tree; DFS)
Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...
- Io 异常: The Network Adapter could not establish the connection解决方案
Io 异常: The Network Adapter could not establish the connection解决方案 2016年06月04日 13:30:21 阅读数:46589 Io ...
- php static 变量声明
<?phpfunction test($key){ static $array = array(); /* 静态变量是只存在于函数作用域中的变量,注释:执行后这种变量不会丢失(下次调用这个函数 ...