首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

thrift:idl描述跟跨语言的web服务

2013-04-02 
thrift:idl描述和跨语言的web服务struct User {1: i16 gender 1,2: string username,3: string password

thrift:idl描述和跨语言的web服务
struct User { 1: i16 gender = 1, 2: string username, 3: string password, 4:i32 id}

上面的结构定义与C语言的结构描述很相同,每个字段都有一个唯一标识:1,2,3,4(处于版本管理的原因,推荐使用上唯一标识)。同时还可以有默认值。可以将结构的fields设置为optional,即如果在没有设置值时将不会序列化

?

?

3、容器

thrift的容器是强类型容器,能够与常用语言中的容器想对应,并可使用java泛型的方式进行标注。在thrift中提供了三种容器:

1、list<type> 一个有序元素列表。可翻译为java ArrayList或STL的vector,或者脚本语言中的原生数组,可包含重复数据

2、set<type> 一个无序不重复元素集。与STL的set,java的HashSet,Python的set,或者PHP/Ruby中的原生dictionary

3、map<type1,type2> 一个主键唯一键值映射表,翻译为STL的map,java HashMap,Python dictionary

?

4、异常

与结构的声明一致,唯一不同的是用exception关键字

exception NotFoundException{    1:i16 errorType,    2:string message}

?

?

5、服务

一个服务的定义在语义上相当于面向对象编程中的一个接口。服务的定义如下:

service <name> {  <returntype> <name> (<arguments>)[throws (<exceptions>)]  ...}

?在方法的声明中有一个oneway修饰符,表示客户端只会触发一个请求,而不会监听任何响应,oneway的方法必须是void:

oneway void zip()

一个例子

service UserService{  void saveUser(1:User user),  User get(1:i32 id) throws (1:NotFoundException nfe)}

?同时service也可以从另外的service继承,需要使用关键字extends,这与java的继承关键字一样:

service Calculator extends shared.SharedService 

?

二、其他的说明

1、include

通过include引用其他的thrift文件,默认在当前路径下寻找,也可以在相对路径下寻找,需要通过编译参数-I来设置

?

2、namespace 与java的package作用一样:

namespace java org.java.codelib.thrift.sanamespace python org.java.codelib.thrift.sa

?上面指定了java和python的package,在只有--gen java/python时将会生产响应的package

?

3、指定常量

const i32 INT32CONSTANT = 9853const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}

或枚举:

enum Operation {  ADD = 1,  SUBTRACT = 2,  MULTIPLY = 3,  DIVIDE = 4}

?三、一个例子

下面的例子是thrift分发包中的tutorial,这里对package做了些修改,其他保持不变。这里分别生成python和java的代码,服务端采用python客户端用java来实现跨语言的调用

1、shared.thrift

?

namespace java org.java.codelib.thrift.sanamespace py sharedstruct SharedStruct {1: i32 key2: string value}service SharedService {SharedStruct getStruct(1: i32 key)}

?

2、tutorial.thrift

?

include "shared.thrift"namespace java org.java.codelib.thrift.sanamespace py tutorialtypedef i32 MyIntegerconst i32 INT32CONSTANT = 9853const 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()}

?

3、生成python和java的代理实现代码

thrift>thrift-0.9.0.exe --gen py shared.thriftthrift>thrift-0.9.0.exe --gen py tutorial.thriftthrift>thrift-0.9.0.exe --gen java shared.thriftthrift>thrift-0.9.0.exe --gen java tutorial.thrift

4、PythonServer.py作为服务端python的实现:

import syssys.path.append('../gen-py')from tutorial import Calculatorfrom tutorial.ttypes import *from shared.ttypes import SharedStructfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TBinaryProtocolfrom thrift.server import TServerclass CalculatorHandler:  def __init__(self):    self.log = {}  def ping(self):    print 'ping()'  def add(self, n1, n2):    print 'add(%d,%d)' % (n1, n2)    return n1+n2  def calculate(self, logid, work):    print 'calculate(%d, %r)' % (logid, work)    if work.op == Operation.ADD:      val = work.num1 + work.num2    elif work.op == Operation.SUBTRACT:      val = work.num1 - work.num2    elif work.op == Operation.MULTIPLY:      val = work.num1 * work.num2    elif work.op == Operation.DIVIDE:      if work.num2 == 0:        x = InvalidOperation()        x.what = work.op        x.why = 'Cannot divide by 0'        raise x      val = work.num1 / work.num2    else:      x = InvalidOperation()      x.what = work.op      x.why = 'Invalid operation'      raise x    log = SharedStruct()    log.key = logid    log.value = '%d' % (val)    self.log[logid] = log    return val  def getStruct(self, key):    print 'getStruct(%d)' % (key)    return self.log[key]  def zip(self):    print 'zip()'handler = CalculatorHandler()processor = Calculator.Processor(handler)transport = TSocket.TServerSocket(port=9090)tfactory = TTransport.TBufferedTransportFactory()pfactory = TBinaryProtocol.TBinaryProtocolFactory()server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)# You could do one of these for a multithreaded server#server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)#server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)print 'Starting the server...'server.serve()print 'done.'

5、CalculatorClient作为java的客户端实现:

public class CalculatorClient {    public static void main(String[] args) {        TTransport transport;        try {            transport = new TSocket("localhost", 9090);            TProtocol protocol = new TBinaryProtocol(transport);            Calculator.Client client = new Calculator.Client(protocol);            transport.open();            System.out.println(client.add(12, 20));            transport.close();        } catch (TTransportException e) {            e.printStackTrace();        } catch (TException e) {            e.printStackTrace();        }    }}

6、更多例子见thrift分发包下的tutorial

热点排行