`
一条路一个人
  • 浏览: 25959 次
  • 性别: Icon_minigender_1
  • 来自: 定州市
社区版块
存档分类
最新评论

Thrift初步了解

阅读更多

Thrift是一个可伸缩的跨语言的服务开发框架,对它的介绍就不google再复制了。
当我们在做web开发时,前端可能采用php,python,ruby等脚本语言做用户的交互页面,那业务和数据库的部分不少就用Java来开发了,毕竟做Java开发的程序员的数量还是占大多数的。这时,我们网站或系统的架构就可以页面用php写,业务程序用Java来写(对web开发都熟悉的mvc来说,就是把controller层和service、dao层分开,用不同的语言来写),那不同语言之间的数据交互怎么实现呢(php如何调用java的一个service的方法)?webservice,thrift,avro等框架和技术就可以拿来使用了~
好,直接写demo示例(thrift所用版本为0.9.1):


一、Java
thrift接口定义文件:UserService.thrift

namespace php tService
namespace java tService

service 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

<?php
error_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

<?php
error_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端的代码要修改为:

 

<?php
error_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})"
  end
end

handler = 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.message
end

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

 

四、Python

server代码:ServerDemo.py

__author__ = 'petric'

import sys
sys.path.append('./gen-py')

from UserService import UserService

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

class UserServiceHandler:
    def getUserNameById(self, id):
        return "hello, user(id:%d)" %id

handler = 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 sys
sys.path.append('./gen-py')

from UserService import UserService

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 = 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 perl

use 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 perl

use 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这样一个中间层。

分享到:
评论

相关推荐

    thrift初步了解

    不要认为thrift能在*.thrift文件中定义调度之类的工作 thrift通过IDL(接口描述语言)来生成各种语言需要的接口代码。 执行thrift文件命令: java:thrift-0.9.1.exe --gen java test.thrift java:thrift-0.9.1.exe ...

    thrift实现http协议案例

    首先,让我们了解一下Thrift的基本工作原理。Thrift基于接口描述语言(IDL),开发者可以在IDL文件中定义服务接口和数据类型。例如: ```thrift service MyService { string echo(1: string msg) } ``` 这个服务...

    使用wireshark抓取thrift协议接口调用

    1. **了解Thrift协议** Thrift基于二进制协议,它定义了服务接口、数据结构(如结构体、枚举)和通信机制。Thrift文件(.thrift)是接口定义语言(IDL),用于描述服务和数据类型。生成的代码支持多种编程语言,如...

    Windows下QT使用Thrift的样例

    总之,这个样例项目提供了一个很好的起点,帮助开发者了解如何在Windows上用QT与Thrift协同工作,同时利用Boost库增强功能。通过实践,你可以更好地理解和掌握这些技术,为你的项目带来高效、跨平台的解决方案。

    thrift样例操作实例

    在"thrift样例操作实例"中,我们可以了解到Thrift的基本用法和工作流程。 首先,`Thrift简介.docx`可能是关于Thrift的入门文档,介绍了Thrift的概念、特点和用途。Thrift的主要特点包括高效、类型安全以及支持多种...

    thrift安装

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年开源,现在由Apache软件基金会维护。它的主要功能是定义数据结构和服务接口,然后自动生成多种编程语言的代码,实现这些接口,使得不同语言之间可以进行...

    Thrift-java学习小结

    Thrift是Facebook开源的一款高性能、跨语言的服务框架,它的设计目标是高效地在不同编程语言之间进行通信。本文将基于Thrift的Java实现,总结学习过程中的一些关键知识点,旨在帮助理解Thrift的工作原理以及如何在...

    thrift官方代码+与dubbo集成支持原生thrift协议

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年设计并发布,其目的是为了在各种编程语言之间提供高效的、轻量级的通信机制。Thrift通过定义一种中间表示(IDL,Interface Definition Language)来描述...

    maven-thrift-server

    【 Maven-Thrift-Server:构建Thrift服务的Maven实践】 在软件开发中,Thrift是一种高效的跨语言服务开发框架,由Facebook开发并开源。它允许定义数据类型和服务接口,然后自动生成各种编程语言的代码,使得不同...

    qt 实现thrift的一个例子

    在IT行业中,Thrift是一种高性能、可扩展的跨语言服务开发框架,由Facebook开源,用于构建分布式服务。它通过定义一种中间表示(IDL,接口定义语言)来描述服务,然后自动生成不同编程语言的代码,使得不同语言之间...

    maven ant thrift0.9.0

    标题 "maven ant thrift0.9.0" 涉及到的是三个关键的软件开发工具:Thrift 0.9.0、Apache Ant 和 Apache ...在实际操作中,开发者需要了解每个工具的用法,编写或修改相应的构建脚本,以便在项目中顺利集成Thrift服务。

    thrift-delphi实例

    Thrift Delphi实例详解 Thrift,全称为“Transportation Layer Security”,是由Facebook开源的一款高性能、跨语言的服务框架。它最初设计的目的是解决大规模分布式系统中的数据通信问题,通过定义一种中间表示...

    C++(Qt)下的thrift的使用示例

    而Thrift则是一种开源的软件框架,用于构建可伸缩的服务,它支持多种编程语言,包括C++,并且允许不同语言之间进行高效的数据交换。在这个“C++(Qt)下的thrift的使用示例”中,我们将探讨如何在Qt项目中集成和使用...

    thrift环境配置方法

    Thrift 环境配置方法 Thrift 是一个跨语言的 RPC 框架,由 Facebook 开发,用于建立高性能的服务之间的远程过程调用。为了使用 Thrift,需要配置好相关的环境,这篇文章将介绍 Thrift 环境配置的方法。 Thrift ...

    thrift-Demo

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年开发并开源,后来成为Apache软件基金会的顶级项目。Thrift的核心思想是通过定义一种中间描述文件(.thrift),来实现数据结构和服务接口的跨语言共享。这...

    Thrift-0.5.exe

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年开发并开源,后来成为Apache软件基金会的顶级项目。Thrift的主要目的是解决分布式系统中的通信问题,它允许开发者定义服务接口,并自动生成相应的客户端和...

    the programmer's guide to apache thrift

    Apache Thrift is an open source cross language serialization and RPC framework. With support for over 15 programming languages, Apache Thrift can play an important role in a range of distributed ...

    mac thrift 0.9.3安装

    mac 想安装低版本thrift 0.9.3太难了,高版本比较简单 直接执行 brew install thrift.rb 即可安装

    thrift包及其源码

    通过这个压缩包,我们可以深入了解Thrift的工作原理,并且可以根据需求进行定制化开发。 1. **Thrift简介**:Thrift的核心思想是定义一种中间语言(IDL,Interface Definition Language),它允许开发者声明服务...

    thrift-编译工具

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年设计并发布,其主要目的是解决大规模分布式系统中的通信问题。Thrift通过定义一种中间表示(IDL,Interface Definition Language),允许开发者在多种编程...

Global site tag (gtag.js) - Google Analytics