2009年3月20日星期五

初试thrift

继上一篇在ubuntu下安装thrift包,在ubuntu下要使用某种语言,还需要安装对应的语言包,比如python,需要使用

import thrift

包的地址也是https://launchpad.net/%7Etxamqpteam/+archive/ppa,下载python-thrift的那个包即可。所以如果要用其他语言,一样要下载扩展包,那个libthrift0,libthrift-dev,java的,erlang的。。。

然后写个最简单的hello 的thrift服务,
hello.thrift:


#!/usr/bin/env thrift

service Hello{
string say(1:string name)
}
先些python版本的,运行thrift --gen py hello.thrift
将在目录下产上一个gen-py的文件夹,进入这个文件夹,可以看到有个hello的文件夹,这就是thrift生成的python代码了,不过服务部分还是需要我们自己搭建,下面来写个hello的服务:
HelloServer.py

from hello import Hello
from hello.ttypes import *

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

class HelloHandler():
def __init__(self):
pass

def say(self, name):
word = "Hello, %s"%(name)
print word
return word

handler = HelloHandler()
processor = Hello.Processor(handler)
transport = TSocket.TServerSocket(9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

print "Starting Server..."
server.serve()

上面的handler实现了say的方法:拿到name参数,增加hello后return出去。然后将handler作为处理器传给server,运行了SimpleServer。thrift默认绑定的端口是9090。
运行:python HelloServer.py 一个Hello的服务器就运行起来了。

接着试一下这个服务,运行hello文件夹里thrift生成的Hello-remote文件:
./Hello-remote say "world"
可以看到在9090端口运行的服务器就返回了 Hello, world了。

自己做个client:
刚才是使用thrift自己生成的Hello-remote的客户端,下面做一个自己的客户端:

#!/usr/bin/env thrift

from hello import Hello
from hello.ttypes import *

from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

try:
transport = TSocket.TSocket("localhost", 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)

client = Hello.Client(protocol)
transport.open()
print client.say("world")
transport.close()
except Thrift.TException, ex:
print "ex:%s"%(ex.message)

代码也很简单,打开9090的端口,通过Hello的client调用say的函数,同样返回Hello, world(就是和服务器端一样,那几个类名比较难记,和服务器通讯也要些不少代码:拿socket,缓存socket,绑定协议)

使用C++调用python服务:
既然facebook用thrift作了代码之间的通讯和粘合,我们就做个C++的client来和python的服务器的这个服务器通讯:
首先是用thrift生成cpp的代码:
thrift --gen cpp hello.thrift
这样就生成了gen-cpp的文件夹,在文件夹下生成了需要的cpp和h文件,下面是client的代码:
(注意要用C++的库,需要安装上面提到的libthrift-dev)
client_remote.cpp:

#include <string>
#include <iostream>

#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TTransportUtils.h>

#include "Hello.h"

using namespace std;

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace boost;

int main(int argc, char* argv[])
{
shared_ptr socket(new TSocket("localhost", 9090));
shared_ptr transport(new TBufferedTransport(socket));
shared_ptr protocol(new TBinaryProtocol(transport));

HelloClient client(protocol);
try
{
transport->open();
string input;
string result;
while (true)
{
cout << "Input your name:";
cin >> input;
if (input == "quit") break;
client.say(result, input);
cout << result;
}

transport ->close();
}
return 0;
}

注意库里cpp代码整个在apache::thrift的命名空间里,下载的thrift的20080411的版本中的sample的cpp用的是facebook::thrift的命名空间,是编译不过的。其他代码格式和python版本的client是类似的,也是创建socket,buffer它,调用协议。

Makefile:

BOOST_DIR = /usr/include/boost
THRIFT_DIR = /usr/include/thrift

LIB_DIR = /usr/lib

GEN_SRC = hello_constants.cpp hello_types.cpp Hello.cpp

client:
g++ client_remote.cpp -o HelloClient -I${THRIFT_DIR} -I${BOOST_DIR} -L${LIB_DIR} -lthrift ${GEN_SRC}

make之

运行这个版本的HelloClient,同样可以和服务器正常通信。

---
以上是实验了python和cpp版本的,接下来想尝试java和erlang版本的。

没有评论:

发表评论