java thrift 传输协议_Thrift的java和php数据交互

Thrift是一个软件框架(远程过程调用框架),用来进行可扩展且跨语言的服务的开发,封装了数据传输格式(二进制、json)和网络通信的服务框架,提供多语言(C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml)的网络服务器端和客户端程序组件

适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输相对于JSON和xml无论在性能、传输大小上有明显的优势。

本文以注册服务接口和登录服务器接口为教程,

Thrift开发的几个概念:

Server 服务模型

Handler 数据处理接口

Processor 数据处理对象

Protocol 数据传输协议

Transport 数据传输方式

(1)支持的传输格式

TBinaryProtocol – 二进制格式.

TCompactProtocol – 压缩格式

TJSONProtocol – JSON格式

TSimpleJSONProtocol –提供JSON只写协议, 生成的文件很容易通过脚本语言解析。

TDebugProtocol – 使用易懂的可读的文本格式,以便于debug

(2) 支持的通信方式(数据传输方式)(Transport)

TFileTransport:文件(日志)传输类,允许client将文件传给server,允许server将收到的数据写到文件中。

THttpTransport:采用Http传输协议进行数据传输

TSocket:采用TCP Socket进行数据传输

TZlibTransport:压缩后对数据进行传输,或者将收到的数据解压

下面几个类主要是对上面几个类地装饰(采用了装饰模式),以提高传输效率。

TBufferedTransport:对某个Transport对象操作的数据进行buffer,即从buffer中读取数据进行传输,或者将数据直接写入buffer

TFramedTransport:以frame为单位进行传输,非阻塞式服务中使用。同TBufferedTransport类似,也会对相关数据进行buffer,同时,它支持定长数据发送和接收。

TMemoryBuffer:从一个缓冲区中读写数据

(3)支持的服务模型

TSimpleServer – 简单的单线程服务模型,常用于测试

TThreadedServer - 多线程服务模型,使用阻塞式IO,每个请求创建一个线程。

TThreadPoolServer – 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。

TNonblockingServer – 多线程服务模型,使用非阻塞式IO(需使用TFramedTransport数据传输方式)

处理大量更新的话,主要是在TThreadedServer和TNonblockingServer中进行选择。TNonblockingServer能够使用少量线程处理大量并发连接,但是延迟较高;TThreadedServer的延迟较低。实际中,TThreadedServer的吞吐量可能会比TNonblockingServer高,但是TThreadedServer的CPU占用要比TNonblockingServer高很多。

服务端编写的一般步骤:

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的方法

下面开始正式代码教程

服务描述文件test.thrift,定义了login服务和register

/**

* The first thing to know about are types. The available types in Thrift are:

*

*  bool        Boolean, one byte

*  byte        Signed byte

*  i16         Signed 16-bit integer

*  i32         Signed 32-bit integer

*  i64         Signed 64-bit integer

*  double      64-bit floating point value

*  string      String

*  binary      Blob (byte array)

*  map  Map from one type to another

*  list    Ordered list of one type

*  set     Set of unique elements of one type

*

* Did you also notice that Thrift supports C style comments?

*/

namespace java com.penngo

namespace php com.penngo

struct User {

1: i64 id,

2: string name,

3: string password

}

service LoginService{

User login(1:string name, 2:string psw);

}

service RegisterService{

User createUser(1:string name, 2:string psw);

}

使用thrift生成对应平台语言代码

thrift -gen java test.thrift

thrift -gen php test.thrift

如果php需要生成服务器端,需求改为thrift -gen php:server test.thrift

java

实现LoginServiceImpl.java登录接口业务

import org.apache.thrift.TException;

public class LoginServiceImpl implements LoginService.Iface{

public LoginServiceImpl(){

}

public User login(String name, String psw) throws TException{

User user = null;

if(name.equals("penngo") && psw.equals("123")){

user = new User();

user.setId(1);

user.setName("penngo");

}

return user;

}

}

实现RegisterServiceImpl.java注册接口业务

import org.apache.thrift.TException;

public class RegisterServiceImpl implements RegisterService.Iface{

public RegisterServiceImpl(){

}

public User createUser(String name, String psw) throws TException{

User user = new User();

user.setId(2);

user.setName(name);

user.setPassword(psw);

return user;

}

}

服务器端java代码

package com.penngo.main;

import org.apache.thrift.TMultiplexedProcessor;

import org.apache.thrift.server.TServer;

import org.apache.thrift.server.TThreadPoolServer;

import org.apache.thrift.transport.TServerSocket;

import org.apache.thrift.transport.TTransportException;

import com.penngo.LoginService;

import com.penngo.LoginServiceImpl;

import com.penngo.RegisterService;

import com.penngo.RegisterServiceImpl;

public class Server {

private void start() {

try {

TServerSocket serverTransport = new TServerSocket(7911);

// 用户登录

LoginService.Processor loginProcessor = new LoginService.Processor(

new LoginServiceImpl());

// 用户注册

RegisterService.Processor registerProcessor = new RegisterService.Processor(

new RegisterServiceImpl());

// Factory protFactory = new TBinaryProtocol.Factory(true, true);

// TServer server = new TThreadPoolServer(new

// TThreadPoolServer.Args(serverTransport)

// .processor(loginProcessor));

TMultiplexedProcessor processor = new TMultiplexedProcessor();

processor.registerProcessor("LoginService", loginProcessor);

processor.registerProcessor("RegisterService", registerProcessor);

TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(

serverTransport).processor(processor));

System.out.println("Starting server on port 7911 ...");

server.serve();

} catch (TTransportException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String args[]) {

Server srv = new Server();

srv.start();

}

}

客户端java

package com.penngo.main;

import org.apache.thrift.*;

import org.apache.thrift.protocol.*;

import org.apache.thrift.transport.*;

import com.penngo.LoginService;

import com.penngo.RegisterService;

import com.penngo.User;

public class Client {

public static void main(String[] args) {

try {

TTransport transport = new TSocket("localhost", 7911);

TProtocol protocol = new TBinaryProtocol(transport);

TMultiplexedProtocol mp1 = new TMultiplexedProtocol(protocol,

"LoginService");

// TProtocol protocol = new TBinaryProtocol(transport);

// LoginService.Client client = new LoginService.Client(protocol);

LoginService.Client loginClient = new LoginService.Client(mp1);

TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol,

"RegisterService");

RegisterService.Client registerClient = new RegisterService.Client(

mp2);

transport.open();

User user = loginClient.login("penngo", "123");

if (user != null) {

System.out.println("登录成功:" + user.getId() + " "

+ user.getName());

} else {

System.out.println("登录失败");

}

User user2 = registerClient.createUser("test", "123");

if (user2 != null) {

System.out.println("创建用户成功:" + user2.getId() + " "

+ user2.getName());

} else {

System.out.println("创建用户失败");

}

transport.close();

} catch (TException x) {

x.printStackTrace();

}

}

}

客户端php

namespace com\penngo;

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

//echo __DIR__.'/../../lib/Thrift/ClassLoader/ThriftClassLoader.php';

use Thrift\ClassLoader\ThriftClassLoader;

$GEN_DIR = realpath(dirname(__FILE__)).'/../../gen-php';

$loader = new ThriftClassLoader();

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

//$loader->registerDefinition('shared', $GEN_DIR);

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

$loader->register();

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

ini_set("display_errors", "stderr");

}

use Thrift\Protocol\TBinaryProtocol;

use Thrift\Protocol\TMultiplexedProtocol;

use Thrift\Transport\TSocket;

use Thrift\Transport\THttpClient;

use Thrift\Transport\TBufferedTransport;

use Thrift\Exception\TException;

use com\penngo\RegisterServiceClient;

use com\penngo\LoginServiceClient;

try {

if (array_search('--http', $argv)) {

//$socket = new THttpClient('localhost', 8080, '/php/PhpServer.php');

} else {

$socket = new TSocket('localhost', 7911);

}

$transport = new TBufferedTransport($socket, 1024, 1024);

$protocol = new TBinaryProtocol($transport);

$loginProtocol = new TMultiplexedProtocol($protocol, "LoginService");

$registerProtocol = new TMultiplexedProtocol($protocol, "RegisterService");

$loginClient = new LoginServiceClient($loginProtocol);

$registerClient = new RegisterServiceClient($registerProtocol);

$transport->open();

$user = $loginClient->login('penngo', '123');

print "user===={$user->id} {$user->name} \n";

$user = $registerClient->createUser('test', '123456');

print "user===={$user->id} {$user->name} \n";

$transport->close();

} catch (TException $tx) {

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

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

}

?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值