作者:ys250
来源:http://www.ys250.com/2010/07/03/thrift_py_php/
thrift是由facebook开发的轻量级跨语言的服务框架,现在已经移交到apache基金会下。和他类似的是google出的protocol buffer和ice。 thrift的一大优势就是支持的语言很丰富,它使用自己的IDL语言来描述服务接口和数据交换的格式。
官方网站:http://incubator.apache.org/thrift/
一、安装:
yum -y install gcc-c++ autoconf automake sysconftool boost / boost-devel libtool perl-ExtUtils-MakeMaker gettext-base / gettext gettext-devel liblocale-gettext-perl zlib-devel / byacc bison flex pkgconfig python-devel wget http://apache.freelamp.com/incubator/thrift/0.2.0-incubating/thrift-0.2.0-incubating.tar.gz ./bootstrap.sh ./configure --prefix=/usr/local/thrift --with-ruby=no --with-erlang=no --with-java=no --with-csharp=no --enable-gen-java=no --enable-gen-csharp=no --enable-gen-rb=no --enable-gen-erl=no make make install
二、IDL描述:
- <textarea cols="50" rows="15" name="code" class="c-sharp"># 1.支持的变量类型
- 类型 描述
- bool #true, false
- byte #8位的有符号整数
- i16 #16位的有符号整数
- i32 #32位的有符号整数
- i64 #64位的有符号整数
- double #64位的浮点数
- string #UTF-8编码的字符串
- binary #字符数组
- struct #结构体
- list<type> #有序的元素列表,类似于STL的vector
- set<type> #无序的不重复元素集,类似于STL的set
- map<type1,type2> #key-value型的映射,类似于STL的map
- exception #是一个继承于本地语言的exception基类
- service #服务包含多个函数接口(纯虚函数)
- # 2.摘一段例子上来,让瞧瞧这是啥东东。(本例子文件名为:tutorial.thrift,是本身带的教程。)
- include "shared.thrift"
- namespace cpp tutorial
- namespace java tutorial
- namespace php tutorial
- namespace perl tutorial
- namespace smalltalk.category Thrift.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()
- }
- # 3. 我们来写个 helloworld.thrift
- service HelloWorld{
- string ping(1: string name),
- string getpng(),
- }</textarea>
三、编译 helloworld:
- /usr/local/thrift/bin/thrift -r --gen py helloworld.thrift
- /usr/local/thrift/bin/thrift -r --gen php helloworld.thrift
- #会在当前目录下生成 gen-* 目录。
四、编写服务器端:
- import sys
- sys.path.append('./gen-py')
- from helloworld import HelloWorld
- from helloworld.ttypes import *
- from thrift.transport import TSocket
- from thrift.transport import TTransport
- from thrift.protocol import TBinaryProtocol
- from thrift.server import TServer
- class HellowordHandler:
- def __init__ (self):
- pass
- def ping (self, name):
- print name + ' from server.'
- return "%s from server." % name
- def getpng (self):
- f = open("./logo.png", "rb")
- c = f.read()
- f.close()
- return c
- handler = HellowordHandler()
- processor = HelloWorld.Processor(handler)
- transport = TSocket.TServerSocket(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.'
五、编写客户端:
- <?php
- try{
- $GLOBALS['THRIFT_ROOT'] = './php/src';
- require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
- require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
- require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
- require_once $GLOBALS['THRIFT_ROOT'].'/transport/THttpClient.php';
- require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
- error_reporting(E_NONE);
- $GEN_DIR = './gen-php';
- require_once $GEN_DIR.'/helloworld/HelloWorld.php';
- error_reporting(E_ALL);
- $socket = new TSocket('*.*.*.*', 9090);
- $transport = new TBufferedTransport($socket, 1024, 1024);
- $protocol = new TBinaryProtocol($transport);
- $client = new HelloWorldClient($protocol);
- $transport->open();
- $a = $client->ping('xyq ');
- echo $a;
- $transport->close();
- } catch (TException $tx) {
- print 'TException: '.$tx->getMessage()."/n";
- }
- ?>
按上面的流程就可以写自己的thrift了,我使用py做服务端,用php做客户端,当然也可以使用c++来做服务端。
相关文章:
thrift 安装 http://wiki.apache.org/thrift/ThriftInstallation
redis + thrift + mongodb 数据测试 http://www.ys250.com/2010/09/02/redis-thrift-mongodb-test/
Thrift基本使用 http://hi.baidu.com/infant/blog/item/01fa53436adc79189313c69e.html