thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。thrift最初由facebook开发用做系统内各语言之间的RPC通信。
现在展示我做的API。
1. 安装thrift 后开始写代码。
环境:
Linux version 2.6.18;
Thrift version 0.9.3;
PHP 5.5.9 ;
Python 2.4.3;
部署:
server 端使用 php,
client 端使用 php,
端口监控使用 python,
目录结构:
2. 展示代码:
1. 创建 thrift 文件。
说明:准备使用thrift实现一个获取图片信息的API,这里展示调通的结果。
下面是 thrift 文件 ,文件名: imginfo.thrift
namespace php Img
service ImgInfo{
string getimgInfo(1: string url),
}
2. 生成文件thrift文件中间接口文件
thrift -r --gen php:server imginfo.thrift
官网上面没有添加server参数。我添加sever并测试通过,官网的方法本人没有测试。
会在 imginfo.thrift 的目录生成一个 gen-php 目录,采用不同的语言会生成不同的目录
3. 编写客户端(client)程序
在imginfo.thrift 目录层 创建php目录 用于存放 客户端脚本。
文件名:c.php
需要注意的点 我用黑色粗体标识
1 <?php
2
3 namespace Img\php;
4 # 红色是需要根据自己的实际情况修改目录的点
5 error_reporting(E_ALL);
6
7 require_once '/root/tools/thrift-0.9.3/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php';
8
9 use Thrift\ClassLoader\ThriftClassLoader;
10
11 $GEN_DIR = realpath(dirname(__FILE__) . '/../') . '/gen-php';
12 $loader = new ThriftClassLoader();
13 $loader->registerNamespace('Thrift', '/root/tools/thrift-0.9.3/lib/php/lib');
14 $loader->registerDefinition('Img', $GEN_DIR);
15 $loader->register();
16
17
18 use Thrift\Protocol\TBinaryProtocol;
19 use Thrift\Transport\TSocket;
20 use Thrift\Transport\THttpClient;
21 use Thrift\Transport\TBufferedTransport;
22 use Thrift\Exception\TException;
23
24 try {
25 if (array_search('--http', $argv)) {
26 $socket = new THttpClient('localhost', 8080, '/php/s.php'); // 实际的server文件地址
27 } else {
28 $socket = new TSocket('localhost', 8080);
29 }
30 $transport = new TBufferedTransport($socket, 1024, 1024);
31 $protocol = new TBinaryProtocol($transport);
32 $client = new \Img\ImgInfoClient($protocol);
33 $transport->open();
34
35 #[ start 根据自己的文件调用就行 ]#################################################
36 $ret = $client->getimgInfo('BBBBBBBBBBBBBBBBBBBB');
37 echo $ret;
38 echo "<br /> \r\n";
39
40 #[ end ]#################################################
41
42 $transport->close();
43 } catch (TException $tx) {
44 print 'TException: ' . $tx->getMessage() . "\n";
45 }
46 ?>
4. 编写服务端(server)端
文件名:s.php ;也放在了php目录下。
需要注意的点 我用黑色粗体标识
1 #! /bin/env php
2 <?php
3 namespace Img\php;
4
5 error_reporting(E_ALL);
6
7 require_once '/root/tools/thrift-0.9.3/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php';
8
9 use Thrift\ClassLoader\ThriftClassLoader;
10
11 $GEN_DIR = realpath(dirname(__FILE__).'/../').'/gen-php';
12
13 $loader = new ThriftClassLoader();
14 $loader->registerNamespace('Thrift', '/root/tools/thrift-0.9.3/lib/php/lib');
15 $loader->registerDefinition('Img', $GEN_DIR);
16 $loader->register();
17 if (php_sapi_name() == 'cli') {
18 ini_set("display_errors", "stderr");
19 }
20
21 use Thrift\Protocol\TBinaryProtocol;
22 use Thrift\Transport\TPhpStream;
23 use Thrift\Transport\TBufferedTransport;
24
25 class ImgInfoHandler implements \Img\ImgInfoIf {
26 protected $log = array();
27 # 编写自己个功能吧
28 public function getimgInfo($name) {
29 return $name . ' ==> client Request server is ok!';
30 }
31
32 };
33
34 header('Content-Type', 'application/x-thrift');
35 if (php_sapi_name() == 'cli') {
36 echo "\r\n";
37 }
38
39 $handler = new \Img\php\ImgInfoHandler();
40 $processor = new \Img\ImgInfoProcessor($handler);
41
42 $transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
43 $protocol = new TBinaryProtocol($transport, true, true);
44
45 $transport->open();
46 $processor->process($protocol, $protocol);
47 $transport->close();
48 ?>
4. 编写端口监控代码。
使用python,用于监控指定端口的http请求并交给s.php 处理
需要注意的使用黑色粗体标识
1 #!/usr/bin/env python
2
3
4
5 import os
6 import BaseHTTPServer
7 import CGIHTTPServer
8
9 # chdir(2) into the tutorial directory.
10 os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
11 # 指定目录 ,如果目录错误 请求会失败
12 class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
13 cgi_directories = ['/php']
14
15
16 BaseHTTPServer.HTTPServer(('', 8080), Handler).serve_forever()
注意: client端请求server的脚本地址 需要和这里的保持一致。
服务端代码也可以改为php:
5. 测试:
1) 开启监控
python r.py
2)c 端请求 s 端
[root@localhost php]# php c.php --http
BBBBBBBBBBBBBBBBBBBB ==> client Request server is ok!<br />
3)python 监控结果展示
[root@localhost php]# python r.py
localhost.localdomain - - [22/Oct/2015 02:36:34] "POST /php/s.php HTTP/1.0" 200 -
6、上述情况只能测试http ,如果直接运行php c.php 会报python 的错,至少在我的环境下。
改掉服务器监控程序为 t.php,c.php 里面运行thrift 的端口改为 9090
1 #! /bin/env php
2 <?php
3 namespace Img\php;
4
5 error_reporting(E_ALL);
6
7 require_once '/root/tools/thrift-0.9.3/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php';
8
9 use Thrift\ClassLoader\ThriftClassLoader;
10
11 $GEN_DIR = realpath(dirname(__FILE__).'/../').'/gen-php';
12
13 $loader = new ThriftClassLoader();
14 $loader->registerNamespace('Thrift', '/root/tools/thrift-0.9.3/lib/php/lib');
15 $loader->registerDefinition('Img', $GEN_DIR);
16 $loader->register();
17 if (php_sapi_name() == 'cli') {
18 ini_set("display_errors", "stderr");
19 }
20
21 use Thrift\Protocol\TBinaryProtocol;
22 use Thrift\Transport\TPhpStream;
23 use Thrift\Transport\TBufferedTransport;
24
25 class ImgInfoHandler implements \Img\ImgInfoIf {
26 protected $log = array();
27 # 编写自己个功能吧
28 public function getimgInfo($name) {
29 return $name . ' ==> client Request server is ok!';
30 }
31
32 };
33
34 header('Content-Type', 'application/x-thrift');
35 if (php_sapi_name() == 'cli') {
36 echo "\r\n";
37 }
38
39 $handler = new \Img\php\ImgInfoHandler();
40 $processor = new \Img\ImgInfoProcessor($handler);
41
42 $transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
43 $protocol = new TBinaryProtocol($transport, true, true);
44
45 $serverTransport = new \Thrift\Server\TServerSocket('localhost',9090);
46 $serverServer = new \Thrift\Server\TForkingServer(
47 $processor,
48 $serverTransport,
49 new \Thrift\Factory\TTransportFactory($transport),
50 new \Thrift\Factory\TTransportFactory($transport),
51 new \Thrift\Factory\TBinaryProtocolFactory(true),
52 new \Thrift\Factory\TBinaryProtocolFactory(false,true)
53 );
54 $serverServer->serve();
55 ?>
7. 再次测试:
1) 开启监控
php t.php
2)c 端请求 s 端 http 模式
[root@localhost php]# php c.php --http
BBBBBBBBBBBBBBBBBBBB ==> client Request server is ok!<br />
3)也可以运行thrift 的模式
[root@localhost php]# php c.php
BBBBBBBBBBBBBBBBBBBB ==> client Request server is ok!<br />
完成,希望对大家有帮助。