thrift是一个用于进行可扩展跨语言服务开发的软件框架,和SOAP以及PHP-RPC不一样的是它还集成了功能强大的代码生成工具,快速构建C++,Java,Python等很多语言代码。下面简单用来做个demo。
首先在官网下载源码包(其中包含了各种语言的依赖库),实现一个拼接字符串的服务,编辑文件test.thrift如下:
service Test {
string combine(1:string str1, 2:string str2)
}
执行命令thrift -r -gen php:server test.thrift生成gen_php文件夹以及Test.php,test_types.php文件。编辑服务器端代码PhpServer.php如下(代码参照tutorial文件夹源码)
<?php
/**
* 引用部分
*/
if (php_sapi_name() == 'cli') {
ini_set("display_errors", "stderr");
}
$GLOBALS['THRIFT_ROOT'] = realpath(dirname(__FILE__).'/../..').'/lib/php/src';
require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TPhpStream.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TServerSocket.php';
require_once $GLOBALS['THRIFT_ROOT'].'/server/TSimpleServer.php';
error_reporting(E_NONE);
/**
* 自定义部分
*/
$GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php';
require_once $GEN_DIR.'/test/test.php';
require_once $GEN_DIR.'/test/test_types.php';
error_reporting(E_ALL);
class TestHandler implements TestIf {
function combine($a,$b)
{
return $a.$b;
}
};
/**
* 启动服务
*/
header('Content-Type', 'application/x-thrift');
if (php_sapi_name() == 'cli') {
echo "\r\n";
}
$handler = new TestHandler();
$processor = new TestProcessor($handler);
$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();
?>
其中
主要需要定义一个handler类继承Test.php文件中的TestIf接口并实现合并字符串功能,这里并没有开启http服务,所以需要把代码以及依赖项拷贝到web服务器目录下。
编辑客户端代码PhpClient.php如下:
<?php
/*
* 依赖项
*/
$GLOBALS['THRIFT_ROOT'] = '../../lib/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.'/test/Test.php';
require_once $GEN_DIR.'/test/test_types.php';
error_reporting(E_ALL);
try {
if (array_search('--http', $argv)) {
$socket = new THttpClient('localhost', 80, '/php/PhpServer.php');
} else {
$socket = new TSocket('192.168.201.172', 9090);
}
$transport = new TBufferedTransport($socket, 1024, 1024);
$protocol = new TBinaryProtocol($transport);
$client = new TestClient($protocol);
$word = $client->combine("I"," don't know");
print "$word\n";
$transport->close();
} catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}
?>
执行客户端代码如下,可以看到已经实现字符串拼接
D:\thrift\tutorial\php>c:\php\php.exe PhpClient.php --http
I don't know
D:\thrift\tutorial\php>
同理,可以用代码生成工具生成其他语言的接口实现,很轻松地就能实现跨语言调用服务。Java客户端如下,运行程序后同样可以得到拼接后的字符串。
package thriftClient;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransport;
import test.Test;
public class Client {
public static void main(String [] args) {
try {
TTransport transport;
transport = new THttpClient("http://127.0.0.1/php/PhpServer.php");
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
Test.Client client = new Test.Client(protocol);
perform(client);
transport.close();
} catch (TException x) {
x.printStackTrace();
}
}
private static void perform(Test.Client client) throws TException
{
String res = client.combine("I", " don't know");
System.out.println(res);
}
}