Thrift实战案例

1、概述
前面一节,我们说了Thrift安装及开发环境准备工作,这一节把主要Thrift IDL规范回顾一下,不常用语法规范在这里不一一列举出来;我们可以把Thrift看作是一个编程语言,那么形成一套语法规范,如接口怎么定义、有什么数据类型、方法怎么定义、变量怎么申明与赋值、命名空间(包)、常量等一系列规定;回答上述的问题,我们就清楚Thrift IDL语法规范,自然知道如何编写thrift文件。

     

    2、数据类型

    2.1 基本数据类型

• bool: 布尔类型
• byte: 字节
• i16: 带符号16位整型
• i32: 带符号32位整型
• i64: 带符号64位整型
• double: 带符号64位浮点型
• string: 字符串类型(UTF-8编码)
Note: There is no support for unsigned integer types, due to the fact that there are no 
native unsigned integer types in many programming languages. Signed integers can be 
safely cast to their unsigned counterparts when necessary.

   

    2.2 特殊类型

binary: 二进制

 

    2.3 结构体类型(类似C语言风构),类似JavaBean定义实体类型

struct bean{
   1:i32 number=10,
   2:i64 bigNumber,
   3:double decimals,
   4:string name="thrifty"
}

 

    2.4 集合类型(包括list、set、map

• list (Maps to c++ STL vector, Java ArrayList etc)
• set (Maps to an STL set, Java HashSet etc)
  PHP doesn’t support sets - so it is treated similar to a List map
• map (Maps to an STL map, Java HashMap etc)
  All the above are the defaults but can be customized to correspond to different 
  types of any language. For this reason custom code generation directives have been 
  added.

    

    3、接口、方法、命名空间定义,关键字service,类似Java接口定义

namespace java com.java // 命名空间定义,规范:namespace + 语言 + 包路径
service Hello{ // 接口定义,类似Java接口定义
   string getWord(), // 方法定义,类似Java接口定义
   void writeWold(1:string words) //参数类型指定
}

 

    4、异常定义

exception InvalidOperation {
  1: i32 what,
  2: string why
}

 

    更多类型定义,如枚举等,请参考官网:https://thrift.apache.org/docs/idl

    

    5、实例步聚

    5.1 定义Thrift文件(hello.thrift)

namespace java com.java
service Hello{
   string getWord(),
   void writeWold(1:string words)
}

 

    5.2 生成Java文件(Hello.java)

    

//执行命令,以Java为例
thrift -r --gen java hello.thrift

    5.3 创建Maven项目,引入thrift包,将Hello.java拷入项目中

<dependency>
  <groupId>org.apache.thrift</groupId>
  <artifactId>libthrift</artifactId>
  <version>0.9.2</version>
</dependency>
<dependency>
  <groupId>commons-codec</groupId>
  <artifactId>commons-codec</artifactId>
  <version>1.9</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.5.8</version>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.12</version>
</dependency>

 

    5.4 编写Thrift接口实现

     

package com.java;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Hello World实现; Hello.Iface为Hello.java中的接口
 *
 */
public class HelloImpl implements Hello.Iface{
	
	private Logger log = LoggerFactory.getLogger(getClass());
	
	@Override
	public String getWord() throws TException {
		
		return "Hello World!";
	}
	
	@Override
	public void writeWold(String words) throws TException {
		log.info("【服务端】:接收客户端信息:"+ words);
	}
	
}

 

    5.5 编写Thrift服务端及客户端

    

/***
* 服务端
*/
package com.java;
import java.net.InetSocketAddress;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.server.TThreadPoolServer.Args;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.java.Hello.Iface;
import com.java.Hello.Processor;

/**
 * Hello World服务端
 * @author oy
 *
 */
public class HelloServer {
	
	private static Logger log = LoggerFactory.getLogger(HelloServer.class);
	// 服务器IP地址
	private String ip;
	// 服务端绑定端口,即监听端口
	private int port;
	
	private static TServerSocket transport;
	
	private static Hello.Processor<Iface> processor;
	
	public HelloServer(String ip, int port){
		this.ip = ip ;
		this.port = port ;
		try {
			transport = new TServerSocket(new InetSocketAddress(this.ip, this.port));
			log.info("Thrif服务器绑定成功!");
		} catch (TTransportException e) {
			log.error("Thrif服务器绑定失败", e);
		}
	}
	
	public void startServer(Iface iface){
		processor = new Processor<Iface>(iface);
		// 协议层:二进制
		Factory factory = new TBinaryProtocol.Factory(true, true);
		// 传输层
		Args args = new Args(transport);
		// 执行处理器(绑定业务逻辑处理器)
		args.processor(processor); 
		args.protocolFactory(factory);
		// 服务
		TServer server = new TThreadPoolServer(args);    
        server.serve();    
	}
	
	public static void main(String[] args) {
		Iface hello = new HelloImpl();
		// 启动服务
		new HelloServer("localhost",9090).startServer(hello);
		log.info("Thrif服务器启动成功!");
	}
}

    

/**
* 客户端
*/
package com.java;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Hello World客户端
 * @author oy
 *
 */
public class HelloClient {
	
	private static Logger log = LoggerFactory.getLogger(HelloClient.class);
	
	public static void main(String[] args) {
		 TTransport transport = null;    
	        try {    
	            transport = new TSocket("localhost", 9090);   
	            // 协议处理
	            TProtocol protocol = new TBinaryProtocol(transport);    
	            Hello.Client client = new Hello.Client(protocol); 
	            transport.open();
	            log.info("【客户端】:获取服务端信息:" + client.getWord()); 
	            client.writeWold("Hello World!");
	            transport.close();    
	            log.info("【客户端】Thrift客户端关闭连接!");  
	        } catch (TTransportException e) {    
	            e.printStackTrace();    
	        } catch (TException e) {    
	            e.printStackTrace();    
	        }    
	}
}

   

    项目相关代码,请收附件!

猜你喜欢

转载自yangyangmyself.iteye.com/blog/2318104
今日推荐