thrift框架搭建的php服务端/客户端代码
2017-03-17 18:52
363 查看
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,具体内容如下:
基本类型:
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,并执行相关命令
如果php的客户端与服务端分开部署的话,需要执行以下命令:
我这里执行的是第一句命令,具体会在gen-php目录下生成三个文件:
生成的三个文件如下图所示:
这三个文件很重要的,如果user.thrift文件格式错误会导致生成失败。
然后先创建服务端文件,userserver.php,内容如下:
客户端文件: userclient.php,代码如下:
输入地址栏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的方法
Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
thrift框架中的客户端和服务器端可以通过二进制数据来传输数据,数据量比起soap,json均更小,可以减少带宽占用。
以下就简单描述以下用框架工作的实际流程:
首先需要在电脑上安装thrift,这里下载的thrift-0.10.0.tar.gz包,可以在github上查到。
然后需要创建一个thrift文件,我这里创建了一个用户相关的文件user.thrift,具体内容如下:
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,并执行相关命令
thrift -gen php:server user.thrift
如果php的客户端与服务端分开部署的话,需要执行以下命令:
thrift -gen php user.thrift
我这里执行的是第一句命令,具体会在gen-php目录下生成三个文件:
生成的三个文件如下图所示:
这三个文件很重要的,如果user.thrift文件格式错误会导致生成失败。
然后先创建服务端文件,userserver.php,内容如下:
<?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,代码如下:
<?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的方法
相关文章推荐
- thrift框架搭建的php服务端/客户端代码
- 用.Net打造一个移动客户端(Android/IOS)的服务端框架NHM(三)——搭建Android开发环境,用Hibernate生成Android项目的Model层
- [PHP]利用XAMPP搭建本地服务器, 然后利用iOS客户端上传数据到本地服务器中(三. PHP端代码实现)
- 用thrift实现客户端和服务端的C++代码 - 金美光的小屋 - 博客频道 - CSDN.NET
- Android客户端与PHP服务端交互(一)---框架概述
- 分享下我学习Thrift的入门例子helloworld,客户端用php,服务端用python
- thrift服务端与客户端代码
- 分享下我学习Thrift的入门例子helloworld,客户端用php,服务端用python:
- windows基于Thrift的php客户端访问java的服务端
- linux epoll机制对TCP 客户端和服务端的监听C代码通用框架实现
- Android客户端与PHP服务端交互(一)---框架概述
- [PHP]利用XAMPP搭建本地服务器, 然后利用iOS客户端上传数据到本地服务器中(四. iOS端代码实现)
- thrift 调取 python php go 客户端代码
- 采用CakePHP框架为Android应用快速搭建Web Service服务器及API接口的PHP代码实例
- 用thrift实现客户端和服务端的C++代码
- python thrift搭建服务端和客户端测试程序
- thrift php客户端编写
- [L-php]表单验证之PHP代码框架
- 从客户端(flex端/flex端)发送到服务端(php)需要注意的问题
- Android 2.0上使用蓝牙通信代码片断(服务端、客户端、数据传输)