做一个 demo 感受一下整个过程,demo是简单的计算器功能。
1 目录结构
|----genphp thrift -r --gen php:server ComputeThrift.thrift
|----lib Thrift 的 lib文件夹
|----ComputeThrift.thrift 接口thrift文件
|----ComputeHandler.php 服务器handler定义文件
|----ComputeServer.php 服务器server代码,用于处理client请求
|----ComputeClient.php 客户端client代码
2 创建thrift文件
namespace php ComputeThrift service ComputeService { i64 plus(1:i64 operator1, 2:i64 operator2) i64 minus(1:i64 operator1, 2:i64 operator2) i64 multiply(1:i64 operator1, 2:i64 operator2) i64 divide(1:i64 operator1, 2:i64 operator2) }
3 生成php server文件
thrift -r --gen php:server ComputeThrift.thrift
重命名为genphp
4 ComputeHandler.php代码
<?php namespace thrift; error_reporting(E_ALL); require_once __DIR__.'/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; use Thrift\ClassLoader\ThriftClassLoader; $gendir = realpath(dirname(__FILE__)).'/genphp'; $loader = new ThriftClassLoader(); $loader->registerNamespace('Thrift', __DIR__.'/lib/php/lib'); $loader->registerDefinition('ComputeThrift', $gendir); $loader->register(); if (php_sapi_name() == 'cli') { ini_set('display_errors',"stderr"); } class ComputeHandler implements \ComputeThrift\ComputeServiceIf { public function plus($op1, $op2){ return $op1 + $op2; } public function minus($op1, $op2) { return $op1 - $op2; } public function multiply($op1, $op2){ return $op1 * $op2; } public function divide($op1, $op2){ return $op1 / $op2; } }
5 ComputeServer.php代码
<?php namespace ComputeThrift\php; error_reporting(E_ALL); require_once __DIR__.'/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; require_once __DIR__.'/ComputeHandler.php'; use Thrift\ClassLoader\ThriftClassLoader; use \thrift\ComputeHandler; $gendir = realpath(dirname(__FILE__)).'/genphp'; $loader = new ThriftClassLoader(); $loader->registerNamespace('Thrift', __DIR__.'/lib/php/lib'); $loader->registerDefinition('ComputeThrift', $gendir); $loader->register(); if (php_sapi_name() == 'cli') { ini_set('display_errors',"stderr"); } use Thrift\ protocol \TBinaryProtocol; use Thrift\Transport\TPhpStream; use Thrift\Transport\TBufferedTransport; use Thrift\ Exception \TException; header('Content-Type','application/x-thrift'); if (php_sapi_name() == 'cli') { echo PHP_EOL; } try { $handler = new ComputeHandler(); $processor = new \ComputeThrift\ComputeServiceProcessor($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 (); } catch(\TException $e) { print 'TException:'.$e-> getMessage ().PHP_EOL; }
6 ComputeClient.php代码
<?php namespace ComputeThrift\php; error_reporting(E_ALL); require_once __DIR__.'/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; use Thrift\ClassLoader\ThriftClassLoader; $gendir = realpath(dirname(__FILE__)).'/genphp'; $loader = new ThriftClassLoader(); $loader->registerNamespace('Thrift', __DIR__.'/lib/php/lib'); $loader->registerDefinition('ComputeThrift', $gendir); $loader->register(); use Thrift\Protocol\TBinaryProtocol; use Thrift\Transport\T socket ; use Thrift\Transport\THttpClient; use Thrift\Transport\TBufferedTransport; use Thrift\Exception\TException; try { if (array_search('--http', $argv)) { $socket = new THttpClient(' localhost ',8080,'/ComputeServer.php'); } else { $socket = new TSocket('localhost',9090); } $transport = new TBufferedTransport($socket, 1024, 1024); $protocol = new TBinaryProtocol($transport); $client = new \ComputeThrift\ComputeServiceClient($protocol); $transport->open(); $op1 = 1; $op2 = 2; $plus = $client->plus($op1, $op2); echo '1 + 2 = '.$plus. "\n"; $minus = $client->minus($op1, $op2); echo '1 - 2 = '.$minus. "\n"; $ multiply = $client->multiply($op1, $op2); echo '1 * 2 = '.$multiply. "\n"; $divide = $client->divide($op1, $op2); echo '1 / 2 = '.$divide. "\n"; $transport->close(); } catch (\Exception $e) { print 'TException:'.$e->getMessage().PHP_EOL; }
7 运行
php -S localhost:8080 #启动server
php Client.php –http #运行client,就会打印出四次算术运算的结果
注:这里只是在client.php里定义socket的host和port,然后转发Server.php文件执行,最终是需要server.php中定义监听端口,这样才是完整的,这里只做测试。