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

Thrift初始了解

2013-11-18 
Thrift初步了解namespace php tServicenamespace java tServiceservice UserService {string getUserNameB

Thrift初步了解
namespace php tServicenamespace java tServiceservice UserService { string getUserNameById(1:i32 userId);}

?

server代码:ServerDemo.java

public class ServerDemo {    public static void main(String[] args) {        try {            UserService.Processor processor = new UserService.Processor(new UserServiceImpl());            TServerTransport transport = new TServerSocket(9090);            TServer server = new TSimpleServer(new TServer.Args(transport).processor(processor));            System.out.println("Starting the simple server...");            server.serve();        } catch (TTransportException e) {            e.printStackTrace();        }    }}

?

client代码:ClientDemo.java

public class ClientDemo {    public static void main(String[] args) {        try {            TTransport transport = new TSocket("localhost", 9090);            TProtocol protocol = new TBinaryProtocol(transport);            UserService.Client client = new UserService.Client(protocol);            transport.open();            System.out.println(client.getUserNameById(24));            transport.close();        } catch (Exception e) {            e.printStackTrace();        }    }}

?

定义的thrift接口文件,通过`thrift --gen java UserService.thrift`就可以得到java的接口类,在windows下运行“thrift.exe"可执行文件。thrift的安装文件,到官网下载然后安装。

在下载的thrift-0.9.1.tar.gz包下的tutorial文件夹下有各种常用语言的demo例子,拿来学习是很不错的资料。在java的例子中除了SimpleServer的例子还有一个secure的例子。

?

二、PHP

client代码:ClientDemo.php

<?phperror_reporting(E_ALL);require_once __DIR__ . "/thrift/lib/Thrift/ClassLoader/ThriftClassLoader.php";use Thrift\ClassLoader\ThriftClassLoader;$GEN_DIR = realpath(dirname(__FILE__) . "/gen-php");$loader = new ThriftClassLoader();$loader->registerNamespace("Thrift", __DIR__ . "/thrift/lib");$loader->registerDefinition("tService", $GEN_DIR);$loader->register();use Thrift\Transport\TSocket;use Thrift\Transport\TBufferedTransport;use Thrift\Protocol\TBinaryProtocol;try {    $socket = new TSocket('localhost', 9090);    $transport = new TBufferedTransport($socket);    $protocol = new TBinaryProtocol($transport);    $client = new \tService\UserServiceClient($protocol);    $transport->open();    $userName = $client->getUserNameById(24);    echo $userName;    $transport->close();} catch (Exception $e) {    echo $e->getMessage();}

?server端的代码,在thrift的tutorial中有一个例子,但是生成的php接口类文件中没有“UserServiceProcessor”类,因为默认执行`thrift --gen php UserService.thrift`生成的php文件中是不包含server端的实现的,要使用php写server程序,需添加参数":server",执行`thrift --gen php:server UserService.thrift`命令生产的php接口类中才会有server的实现。不过看server的代码,并是用到socket的类,所以php的server是有些特殊的,它需要apache的支持。

?

php server代码:ServerDemo.php

<?phperror_reporting(E_ALL);require_once __DIR__ . '/thrift/lib/Thrift/ClassLoader/ThriftClassLoader.php';use Thrift\ClassLoader\ThriftClassLoader;$GEN_DIR = realpath(dirname(__FILE__)) . '/gen-php';$loader = new ThriftClassLoader();$loader->registerNamespace('Thrift', __DIR__ . '/thrift/lib');$loader->registerDefinition("tService", $GEN_DIR);$loader->register();use Thrift\Protocol\TBinaryProtocol;use Thrift\Transport\TPhpStream;use Thrift\Transport\TBufferedTransport;class UserServiceHandler implements \tService\UserServiceIf{    public function getUserNameById($userId)    {        return "hello, user(id:" . $userId . ")";;    }}header('Content-Type', 'application/x-thrift');if (php_sapi_name() == 'cli') {    echo "\r\n";}$userService = new UserServiceHandler();$processor = new \tService\UserServiceProcessor($userService);$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));$protocol = new TBinaryProtocol($transport, true, true);$transport->open();$processor->process($protocol, $protocol);$transport->close();

?把程序包放到apache配置的web目录,我本机环境为ubuntu12.04,所以把项目拷贝到"/var/www/“目录,ServerDemo.php在项目包ThriftDemo根目录下,所以client端的代码要修改为:

?

<?phperror_reporting(E_ALL);require_once __DIR__ . "/thrift/lib/Thrift/ClassLoader/ThriftClassLoader.php";use Thrift\ClassLoader\ThriftClassLoader;$GEN_DIR = realpath(dirname(__FILE__) . "/gen-php");$loader = new ThriftClassLoader();$loader->registerNamespace("Thrift", __DIR__ . "/thrift/lib");$loader->registerDefinition("tService", $GEN_DIR);$loader->register();use Thrift\Transport\TSocket;use Thrift\Transport\TBufferedTransport;use Thrift\Protocol\TBinaryProtocol;use Thrift\Transport\THttpClient;try {    $socket = new THttpClient('localhost', 80, '/ThriftDemo/ServerDemo.php');    $transport = new TBufferedTransport($socket);    $protocol = new TBinaryProtocol($transport);    $client = new \tService\UserServiceClient($protocol);    $transport->open();    $userName = $client->getUserNameById(24);    echo $userName;    $transport->close();} catch (Exception $e) {    echo $e->getMessage();}

?这个时候,运行client的脚本,就可以访问php的thrift server实现类了。第一个的client可以访问java的server,所以php的server不是通过`php ServerDemo.php`来运行脚本的,client端是通过访问apache下的server脚本文件调用服务的。(php的server比java和ruby、python、perl等要繁琐一些,估计也很少用php写thrift的服务端代码)

?

好的,下个语言!

?

三、Ruby

server代码:server_demo.rb

require '../lib/thrift'require '../thrift-demo/gen-rb/user_service'class UserServiceHandler  def getUserNameById(userId)      return "hello, user(id: #{userId})"  endendhandler = UserServiceHandler.new()processor = UserService::Processor.new(handler)transport = Thrift::ServerSocket.new('localhost', 9090)transportFactory = Thrift::BufferedTransportFactory.new()server = Thrift::SimpleServer.new(processor, transport, transportFactory)puts "Starting the server..."server.serve()

?client代码:client_demo.rb

require '../lib/thrift'require '../thrift-demo/gen-rb/user_service'begin  transport = Thrift::BufferedTransport.new(Thrift::Socket.new("localhost", 9090))  protocol = Thrift::BinaryProtocol.new(transport)  client = UserService::Client.new(protocol)  transport.open()  puts client.getUserNameById(24)  transport.close()rescue Thrift::Exception => tx  puts 'Thrift.Exception: ', tx.messageend

?ruby还是很简洁的,执行`thrift --gen rb UserService.thrift`生成ruby的接口类文件,然后依次运行server脚本和client脚本。

?

四、Python

server代码:ServerDemo.py

__author__ = 'petric'import syssys.path.append('./gen-py')from UserService import UserServicefrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TBinaryProtocolfrom thrift.server import TServerclass UserServiceHandler:    def getUserNameById(self, id):        return "hello, user(id:%d)" %idhandler = UserServiceHandler()processor = UserService.Processor(handler)transport = TSocket.TServerSocket(port=9090)tFactory = TTransport.TBufferedTransportFactory()pFactory = TBinaryProtocol.TBinaryProtocolFactory()server = TServer.TSimpleServer(processor, transport, tFactory, pFactory)print "starting py server..."server.serve()

?

client代码:ClientDemo.py

__author__ = 'petric'import syssys.path.append('./gen-py')from UserService import UserServicefrom thrift import Thriftfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TBinaryProtocoltry:    transport = TSocket.TSocket('localhost', 9090)    transport = TTransport.TBufferedTransport(transport)    protocol = TBinaryProtocol.TBinaryProtocol(transport)    client = UserService.Client(protocol)        transport.open()    print client.getUserNameById(2)    transport.close()except Thrift.TException, tx:    print '%s' % (tx.message)

执行`thrift --gen py UserService.thrift`生成ruby的接口类文件,然后依次运行server脚本和client脚本。

?

但是,这里面还有一个问题,先说java,在pom.xml中加入thrift的依赖配置就可以,这就不说了;php中,在下载的thrift-0.9.1.tar.gz包下的lib目录下有各个语言的thrift的工具包,php下有lib工具包,ruby下也有lib工具包,拿到自己的项目中就行;不过,python和php和ruby不同,它的lib目录下面没有,不过多了个“setup.py“文件,哦,对用python做开发的同学就不用说了,不过对想玩一玩python例子的其它程序员-google一下也就清楚了,执行`sudo python setup.py install`就可以给python添加thrift支持包了。

好,再写一个例子,就当自己也了解一下其它语言的特点了

?

五、Perl

对perl不是很了解,工作中也还没有用到过,先写client试一试

client代码:ClientDemo.pl

#!/usr/bin/env perluse strict;use warnings;use lib '../lib';use lib '../gen-perl';use Thrift;use Thrift::BinaryProtocol;use Thrift::Socket;use Thrift::BufferedTransport;use UserService;my $socket = new Thrift::Socket('localhost', 9090);my $transport = new Thrift::BufferedTransport($socket, 1024, 1024);my $protocol = new Thrift::BinaryProtocol($transport);my $client = new UserServiceClient($protocol);eval{    $transport->open();    print 'connection open...';    my $name = $client->getUserNameById(3);    print "$name\n";    $transport->close();}; if($@){    warn(Dumper($@));}

?访问java,python,ruby的server端没有问题,

server代码:ServerDemo.pl

#!/usr/bin/env perluse strict;use warnings;use lib '../lib';use lib '../gen-perl';use Thrift;use Thrift::Socket;use Thrift::Server;use UserService;package UserServiceHandler;use base qw(UserServiceIf);sub new {    my $classname = shift;    my $self      = {};    return bless($self,$classname);}sub getUserNameById{    my($self, $userId) = @_;    return ("hello, user(id:$userId)\n");}eval {    my $handler = new UserServiceHandler;    my $processor = new UserServiceProcessor($handler);    my $serversocket = new Thrift::ServerSocket(9090);    my $forkingserver = new Thrift::ForkingServer($processor, $serversocket);    print "Starting perl server...\n";    $forkingserver->serve();}; if($@) {    if ($@ =~ m/TException/ and exists $@->{message}) {        my $message = $@->{message};        my $code    = $@->{code};        my $out     = $code . ':' . $message;        die $out;    } else {        die $@;    }}

?我的系统自带的perl的版本是5.14.2,不过和python差不多也得安装一下环境,但不是python那样安装python的thrift工具包,perl也是把它的lib目录拷贝到自己的项目就可以。运行脚本报了一些错误,一些类啊文件什么的好像没有,google一下,下载了Class-Accessor-0.34.tar.gz,然后安装上(解压,make install),又执行`sudo apt-get install libbit-vector-perl`,把perl的lib下的文件也跑了一下`perl Makefile.PL`和?`make install`。这样perl脚本的server和client都可以跑了,测试正常输出结果。

?

六、js

在tutorial中还有js的例子,js不能访问通常的server的,都是通过socket创建的,只能通过ajax访问通过JSON protocol 和 HTTP transport开启的服务,照着tutorial的例子写了一遍,server用java写的,用到apache的httpcomponents包,启动一个http的server,指定自己的html(包含js的client端)文件所在的目录为webapp,通过设定的端口访问自己的html页面,如“http://localhost:8088/Client_Html.html“,这样js就可以访问thrift的接口服务了!哇~,这个例子最麻烦了,代码就不拷贝过来了。由于js的ajax通常情况下是跨不了域的,所以js的client端和server端需在一个域名下,例子中使用的HttpService相当与模拟了一个web server(apache,tomcat等),那js请求的是一个url,如“/UserService/getUserNameById“,server端遇到该url会通过Processor调用实现类返回结果,其它的文件url就直接返回文件了。简单点就可以理解为:js要想访问thrift的service服务需通过web server这样一个中间层。

热点排行