参考文章: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框架学习的更多相关文章

  1. thrift框架总结,可伸缩的跨语言服务开发框架

    thrift框架总结,可伸缩的跨语言服务开发框架 前言: 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等.其 ...

  2. IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API

    IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习之保护API. 使用IdentityServer4 来实现使用客户端凭据保护ASP.N ...

  3. Hadoop学习笔记—18.Sqoop框架学习

    一.Sqoop基础:连接关系型数据库与Hadoop的桥梁 1.1 Sqoop的基本概念 Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据移植过去并不容易.Apache Sqoop正在加 ...

  4. Spring框架学习一

    Spring框架学习,转自http://blog.csdn.net/lishuangzhe7047/article/details/20740209 Spring框架学习(一) 1.什么是Spring ...

  5. EF框架学习手记

    转载: [ASP.NET MVC]: - EF框架学习手记 1.EF(Entity Framework)实体框架EF是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架 ...

  6. web框架学习列表

    转载自鲁塔弗的博客,原文网址:http://lutaf.com/148.htm web framework层出不穷,特别是ruby/python,各有10+个,php/java也是一大堆 根据我自己的 ...

  7. 2013 最新的 play web framework 版本 1.2.3 框架学习文档整理

    Play framework框架学习文档 Play framework框架学习文档 1 一.什么是Playframework 3 二.playframework框架的优点 4 三.Play Frame ...

  8. SSH 框架学习之初识Java中的Action、Dao、Service、Model-收藏

    SSH 框架学习之初识Java中的Action.Dao.Service.Model-----------------------------学到就要查,自己动手动脑!!!   基础知识目前不够,有感性 ...

  9. 各种demo——CI框架学习

    各种demo——CI框架学习   寒假学习一下CI框架,请各位多多指教! 一.CI的HelloWorld! 注意:CI禁止直接通过文件目录来访问控制器. ./application/controlle ...

随机推荐

  1. c++builder 读写文件类

    c++builder 读写文件类 TStreamReader.TStreamWriter读取一行 http://docwiki.embarcadero.com/CodeExamples/XE8/en/ ...

  2. Thread(线程)三

    今天我们继续接着线程讲讲,上一章提到一下task概念, 首先接着task继续往下讲,在前章节提到过Thread怎么实现其他线程完成后再让主线程继续执行的功能,那么如果Task也需要线程等待事件,该怎么 ...

  3. HTTP 1.0 & 1.1

    简介: HTTP ( HyperText Transfer Protocol ) 超文本传输协议,是互联网上应用最广泛的一种网络协议. HTTP 是一个客户端和服务端请求.应答的标准.使用 WEB 浏 ...

  4. PHP获取页面执行时间的方法(推荐)

    一些循环代码,有时候要知道页面执行的时间,可以添加以下几行代码到页面头部和尾部: 头部:$stime=microtime(true); 尾部: $etime=microtime(true);//获取程 ...

  5. Spring IOC的配置使用

    1.1.1 XML配置的结构一般配置文件结构如下: <beans> <import resource=”resource1.xml” /> <bean id=”bean1 ...

  6. Mesos的资源分配

    Apache Mesos能够成为最优秀的数据中心资源管理器的一个重要功能是面对各种类型的应用,它具备像交警一样的疏导能力.本文将深入Mesos的资源分配内部, 探讨Mesos是如何根据客户应用需求,平 ...

  7. SQL SERVER性能优化综述

    SQL SERVER性能优化综述 一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开发阶段的事情,而是在整个软件生命周期都需要注意,进行有效工作才能达到的.所以我希望按照软 ...

  8. Python之多进程和多线程

    目标: 1.os.fork简单示例 2.使用os.fork多进程测试IP是否在线 3.使用os.fork多进程解决tcpserver多客户端连接问题 4.多线程测试IP地址是否在线 1.os.fork ...

  9. Spring在代码中获取bean的几种方式(转)

    获取spring中bean的方式总结: 方法一:在初始化时保存ApplicationContext对象 ApplicationContext ac = new FileSystemXmlApplica ...

  10. static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较

    隐式转换(implicit conversion) ; int b; b=a; short是两字节,int是四字节,由short型转成int型是宽化转换(bit位数增多),编译器没有warning,如 ...