您的位置:首页 > 编程语言 > PHP开发

thrift框架搭建的php服务端/客户端代码

2017-04-28 22:38 369 查看
Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP,
Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js,
Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。

Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

thrift框架中的客户端和服务器端可以通过二进制数据来传输数据,数据量比起soap,json均更小,可以减少带宽占用。

以下就简单描述以下用框架工作的实际流程:

首先需要在电脑上安装thrift,这里下载的thrift-0.10.0.tar.gz包,可以在github上查到。

然后需要创建一个thrift文件,我这里创建了一个用户相关的文件user.thrift,具体内容如下:

[html] view
plain copy







namespace php UserModule

struct User {

1:optional i64 id,

2:required string username,

3:optional string email,

4:optional string password,

5:optional i32 age,

6:optional string tel

}

exception InvalidException {

1:i32 code,

2:string message

}

enum UserStatus {

DefaultValue=0, //新创建未认证

isAuthed=1, //已认证

isDeleted=2 //已删除

}

struct InParamsUser {

1:optional string username,

2:optional i32 age,

3:optional string email,

4:optional string tel,

5:optional i32 status = UserStatus.DefaultValue,

6:optional i32 page,

7:optional i32 pageSize

}

struct OutputParamsUser {

1:i32 page,

2:i32 pageSize,

3:i32 totalNum,

4:list<User> records

}

service LoginService {

User Login(1:string username, 2:string pwd) throws (1:InvalidException ex),

User Register(1:string username,2:string pwd) throws (1:InvalidException ex),

string getCheckCode(1:string sessionid) throws (1:InvalidException ex),

string verifyCheckCode(1:string sessionid, 2:string checkcode) throws (1:InvalidException ex)

}

service UserService {

User Detail(1:i64 id) throws (1:InvalidException ex),

User Update(1:User user) throws (1:InvalidException ex),

OutputParamsUser search(1:InParamsUser inParams),

map<i32,string> getAllStatus()

}

基本类型:

bool:布尔值,true 或 false,对应 Java 的 boolean
byte:8 位有符号整数,对应 Java 的 byte
i16:16 位有符号整数,对应 Java 的 short
i32:32 位有符号整数,对应 Java 的 int
i64:64 位有符号整数,对应 Java 的 long
double:64 位浮点数,对应 Java 的 double
string:utf-8编码的字符串,对应 Java 的 String

结构体类型:

struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean

容器类型:

list:对应 Java 的 ArrayList
set:对应 Java 的 HashSet
map:对应 Java 的 HashMap

异常类型:

exception:对应 Java 的 Exception

服务类型:

service:对应服务的类

然后根据该thrift文件生成相应的service、types文件

这里先把虚拟机上的Linux项目文件列举一下:

首先这是网站根目录下的thrift文件夹



然后在ThriftGen目录下放入user.thrift,并执行相关命令

[html] view
plain copy







thrift -gen php:server user.thrift

如果php的客户端与服务端分开部署的话,需要执行以下命令:

[html] view
plain copy







thrift -gen php user.thrift

我这里执行的是第一句命令,具体会在gen-php目录下生成三个文件:



生成的三个文件如下图所示:



这三个文件很重要的,如果user.thrift文件格式错误会导致生成失败。

然后先创建服务端文件,userserver.php,内容如下:

[php] view
plain copy







<?php

namespace UserModule\php;

error_reporting(E_ALL);

require_once __DIR__.'/PHP/Thrift/ClassLoader/ThriftClassLoader.php';

use Thrift\ClassLoader\ThriftClassLoader;

$GEN_DIR = __DIR__.'/ThriftGen/gen-php';

$loader = new ThriftClassLoader();

$loader->registerNamespace('Thrift', __DIR__ . '/PHP');

$loader->registerDefinition('UserModule', $GEN_DIR);

$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\TMultiplexedProcessor;

use \UserModule\User;

use \UserModule\InvalidException;

class LoginServiceHandler implements \UserModule\LoginServiceIf

{

public function Login($username, $pwd)

{

}

public function Register($username, $pwd)

{

$objUser = new User();

if($username=='wangzhongwei') {

throw new InvalidException(array('code'=>111,'message'=>'该用户已经注册!'));

}else {

$objUser->username = $username;

$objUser->password = $pwd;

$objUser->id = 1;

$objUser->age = 33;

$objUser->email = 'areyouok@163.com';

$objUser->tel = '13716857451';

}

return $objUser;

}

public function getCheckCode($sessionid)

{

}

public function verifyCheckCode($sessionid, $checkcode)

{

}

}

class UserServiceHandler implements \UserModule\UserServiceIf

{

public function Detail($id)

{

$objUser = new User();

if($id == 1) {

$objUser->username = 'wangxiaoxiao';

$objUser->password = 'howareyouok';

$objUser->id = 1;

$objUser->age = 34;

$objUser->email = 'areyouok@163.com';

$objUser->tel = '13716857451';

}

return $objUser;

}

public function Update(\UserModule\User $user)

{

$objUser = new User();

if($user->id == 1) {

$objUser->id = $user->id;

$objUser->username = $user->username;

$objUser->age = $user->age;

$objUser->email = $user->email;

$objUser->tel = $user->tel;

}

return $objUser;

}

public function search(\UserModule\InParamsUser $inParams)

{

$result = new \UserModule\OutputParamsUser();

$result->page = $inParams->page;

$result->pageSize = $inParams->pageSize;

$result->totalNum = 1;

$arrUsers = [];

$objUser = new User();

$objUser->username = 'wangxiaoxiao';

$objUser->password = 'howareyouok';

$objUser->id = 1;

$objUser->age = 34;

$objUser->email = 'areyouok@163.com';

$objUser->tel = '13716857451';

$arrUsers[] = $objUser;

$objUser1 = clone $objUser;

$objUser1->username = 'whatareyoudoing';

$objUser1->tel = '13855254475';

$arrUsers[] = $objUser1;

$result->records = $arrUsers;

return $result;

}

public function getAllStatus()

{

return [0=>'新创建',1=>'已认证',2=>'已删除'];

}

}

header('Content-Type', 'application/x-thrift');

if (php_sapi_name() == 'cli') {

echo "\n";

}

$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));

$protocol = new TBinaryProtocol($transport, true, true);

$tMultiplexedProcessor = new TMultiplexedProcessor();

$loginService = new LoginServiceHandler();

$loginServiceProcessor = new \UserModule\LoginServiceProcessor($loginService);

$tMultiplexedProcessor->registerProcessor('loginService', $loginServiceProcessor);

$userService = new UserServiceHandler();

$userServiceProcessor = new \UserModule\UserServiceProcessor($userService);

$tMultiplexedProcessor->registerProcessor('userService', $userServiceProcessor);

$transport->open();

try{

$tMultiplexedProcessor->process($protocol, $protocol);

} catch(TException $e) {

$transport->close();

throw $e;

}

$transport->close();

客户端文件: userclient.php,代码如下:

[html] view
plain copy







<?php

namespace UserModule\php;

error_reporting(E_ALL);

require_once __DIR__.'/PHP/Thrift/ClassLoader/ThriftClassLoader.php';

use Thrift\ClassLoader\ThriftClassLoader;

$GEN_DIR = __DIR__.'/ThriftGen/gen-php';

$loader = new ThriftClassLoader();

$loader->registerNamespace('Thrift', __DIR__ . '/PHP');

$loader->registerDefinition('UserModule', $GEN_DIR);

$loader->register();

use Thrift\Protocol\TBinaryProtocol;

use Thrift\Protocol\TMultiplexedProtocol;

use Thrift\Transport\THttpClient;

use Thrift\Transport\TBufferedTransport;

use Thrift\Exception\TException;

use UserModule\InvalidException;

use UserModule\User;

try {

$socket = new THttpClient('localhost', 80, '/thrift/userserver.php');

$transport = new TBufferedTransport($socket);

$protocol = new TBinaryProtocol($transport);

$loginProtocol = new TMultiplexedProtocol($protocol, 'loginService');

$loginService = new \UserModule\LoginServiceClient($loginProtocol);

$result = $loginService->Register('wangzhongwei','areyouok');

var_dump($result);

echo '<br/>';

// $result = $loginService->login('wangzhongwei','areyouok');

// var_dump($result);

// echo '<br/>';

$userProtocol = new TMultiplexedProtocol($protocol, 'userService');

$userService = new \UserModule\UserServiceClient($userProtocol);

$result = $userService->Detail(1);

var_dump($result);

echo '<br/>';

$result->age = $result->age+3;

$result = $userService->Update($result);

var_dump($result);

echo '<br/>';

$params = new \UserModule\InParamsUser();

$params->page = 1;

$params->pageSize = 10;

$result = $userService->search($params);

var_dump($result);

echo '<br/>';

$result = $userService->getAllStatus();

var_dump($result);

echo '<br/>';

$transport->close();

} catch (InvalidException $tx) {

print 'TException: '.$tx->getCode().' '.$tx->getMessage()."\n";

}

输入地址栏URL地址:http://192.168.3.199/thrift/userclient.php,没有报错就ok.

本例程序还是以http协议的方式对外提供,也可以通过服务的方式提供接口。

如果需要将该代码以服务的形式对外提供,大致步骤如下:

服务端编写的一般步骤:

1. 创建Handler

2. 基于Handler创建Processor

3. 创建Transport(通信方式)

4. 创建Protocol方式(设定传输格式)

5. 基于Processor, Transport和Protocol创建Server

6. 运行Server

客户端编写的一般步骤:

1. 创建Transport

2. 创建Protocol方式

3. 基于Transport和Protocol创建Client

4. 运行Client的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php thrift
相关文章推荐