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

上边概述内容参考自:http://elf8848.iteye.com/blog/1960131

下面开始正式代码教程

服务描述文件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<t1,t2>  Map from one type to another
 *  list<t1>    Ordered list of one type
 *  set<t1>     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

<?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";
}

?>
时间: 2024-10-27 09:12:58

Thrift的java和php数据交互的相关文章

html、java、mysql数据交互

此文用于java学习,在此小记. 在此之前有写过一些小的Java Demo,由于时间隔得比较长故而淡忘了,重新拾起. 环境的安装 开发环境:Win7(x64)+MyEclipse 2014+Mysql5.5.34+Navicat MyEclipse 2014的安装和破解网上有很多资料,可自行查找,这里不再过多叙述.我这里安装的是myeclipse-pro-2014-GA-offline-installer-windows,破解文件用的是Myeclipse-2014-破解文件.顺便安装了一个web

html、java、mysql数据交互之数据分页显示

在上文中我们已经从数据库中获取到了数据,并且可以显示在html页面上.本文是继上文之后,将获取到的数据集进行处理之后显示在页面上. 从所接触的知识面,这里想到了有两种方案. 一.使用容器将获得的数据保存起来,然后显示到页面上. 二.重写ResultSet类方法,实现ResultSet的分页,并使用jsp显示到页面上. 两种方式都可行,考虑到大数据的效率问题,这里选择了方法二. 一.重写ResultSet类,实现记录集的分页 1.添加Pageable接口 package com.cn.page;

java不同对象之间的数据交互(通用)

??java中万物皆对象.不论你是线程,还是异步任务,还是...都可以用以下的三种通用方法来进行对象间数据的交互.当然android相比java有自己独特的数据交互方式,这些会在后面的文章中讲到,本篇文章意在对java通用的对象间的数据交互进行总结. 一.通过构造函数传递 ??构造函数很大程度上是方便参数的传递,以达到在新建对象的时候,同时对这个对象的一些属性进行初始化.我们经常需要根据自己的需要,重载类的构造方法.我们可以在对象初建的时候把它需要的数据传递给它,以实现不同对象之间数据的交互.

java与c/c++之间的数据交互-----jni点滴

淡泊明志.宁静致远 A Diamond is just a piece of Coal that did well under Pressure. java与c/c++之间的数据交互-----jni点滴[转] 最近作一个tiemsten数据库的项目,用到了jni技术.在这个项目中,我们用java来写界面和业务逻辑,用c语言写数据库odbc访 问.单纯的odbc其实没有什么难的,但是在java和c之间进行数据传递是比较麻烦的事情.两者之间数据的传递有这样几种情况:java和c之间基本数 据类型的交

Java之基于S2SH与手机数据交互(一)

在前两篇博客,介绍了在eclipse上搭建SSH,可是好多小伙伴反映.看了偶写滴博客.跟着搭建还是错误百出,唉! 事实上不经历错误怎么能不见红线啊!于是我在上篇博客补充了他们的错误,还在被错误困扰的童鞋,能够去看一看. 今天我们简介一下.怎样在SSH基础上与手机进行数据交互.如今后台给移动端传递数据一般都是以json的格式传递给移动端,然后移动端在对json进行解析.说白了就是给一个链接,打开之后就像下图那样的数据. 像这种数据该怎么给手机端提供呢?接下来就来学习一下怎样给移动端提供数据. (一

AJAX+REA实现前后台数据交互的加密解密

AJAX+REA实现前后台数据交互的加密解密 1.创建js文件Encryption.js /**  * 加密解密  */ /** RSA加密用 生成key */ function bodyRSA(){ /** 1024位的key参数写130,2014位的key参数写260 */ setMaxDigits(130); /** ajax 调用后台方法,取回公钥 */ var keyR ;     $.ajax({      url: "/GHGL/Key/pk",//请求后台的url,本例

浅谈混合开发与Android,JS数据交互

本文是作者原创,如转载请注明出处! 一.概论 现在时代已经走过了移动互联网的超级火爆阶段,市场上移动开发人员已经趋于饱和,显然,只会原生APP的开发已不能满足市场的需求,随着H5的兴起与火爆,H5在原生APP中的使用越来越广泛,也就是我们常说的混合开发(Hybrid APP).最新很火的微信小程序相信大家都是知道的,实际上微信小程序加载的界面就是一个HTML5的界面,HTML5界面在一些电商类的APP中主要承担展示数据的作用,但是他的作用并不仅限于此,最起码js调用原生方法和原生调用js的方法是

Struts2基本使用(三)--数据交互

Struts2中的数据交互 在Struts2中我们不必再使用request.getParameter()这种方式来获取前台发送到服务器的参数. 我们可以在服务器端的Java类中直接声明一个和前台发送数据的同名变量即可,然后生成它的set/get方法即可以实现前后台数据的交互. 假如我们在前台页面中的表单如下: <form method="post" action="demo!register.action"> username:<input typ

springMVC学习(11)-json数据交互和RESTful支持

一.json数据交互: json数据格式在接口调用中.html页面中较常用,json格式比较简单,解析还比较方便. 比如:webservice接口,传输json数据. springMVC进行json交互 1)环境准备: 加载json转换的jar包: springmvc中使用jackson的包进行json转换(@requestBody和@responseBody使用下边的包进行json转) jackson-core-asl-1.9.11.jar jackson-mapper-asl-1.9.11.