1. Thrift类介绍
Thrift代码包(位于thrift-0.6.1/lib/cpp/src)有以下几个目录:

concurrency:并发和时钟管理方面的库
processor:Processor相关类
protocal:Protocal相关类
transport:transport相关类
server:server相关类

 
1.1 Transport类(how is transmitted?)
负责数据传输,有以下几个可用类:
TFileTransport:文件(日志)传输类,允许client将文件传给server,允许server将收到的数据写到文件中;
THttpTransport:采用Http传输协议进行数据传输;
TSocket:采用TCP Socket进行数据传输;
TZlibTransport:压缩后对数据进行传输,或者将收到的数据解压。
下面几个类主要是对上面几个类地装饰(采用了装饰模式),以提高传输效率。
TBufferedTransport:对某个Transport对象操作的数据进行buffer,即从buffer中读取数据进行传输,或者将数据直接写入buffer;
TFramedTransport:同TBufferedTransport类似,也会对相关数据进行buffer,同时,它支持定长数据发送和接收;
TMemoryBuffer:从一个缓冲区中读写数据。
1.2 Protocol类(what is transmitted?)
负责数据编码,主要有以下几个可用类:
TBinaryProtocol:二进制编码
TJSONProtocol:JSON编码
TCompactProtocol:密集二进制编码
TDebugProtocol:以用户易读的方式组织数据
1.3 Server类(providing service for clients)
TSimpleServer:简单的单线程服务器,主要用于测试
TThreadPoolServer:使用标准阻塞式IO的多线程服务器
TNonblockingServer:使用非阻塞式IO的多线程服务器,TFramedTransport必须使用该类型的server
1.5 对象序列化和反序列化 Thrift中的Protocol负责对数据进行编码,因而可使用Protocol相关对象进行序列化和反序列化。
 
 
2.编写client和server
 
2.1 client端代码编写
Client编写的方法分为以下几个步骤:
(1) 定义TTransport,为你的client设置传输方式(如socket, http等)。
(2) 定义Protocal,使用装饰模式(Decorator设计模式)封装TTransport,为你的数据设置编码格式(如二进制格式,JSON格式等)
(3) 实例化client对象,调用服务接口。
说明:如果用户在thrift文件中定义了一个叫${server_name}的service,则会生成一个叫${server_name}Client的对象。
 
2.2 Server端代码编写
(1) 定义一个TProcess,这个是thrift根据用户定义的thrift文件自动生成的类
(2) 使用TServerTransport获得一个TTransport
(3) 使用TTransportFactory,可选地将原始传输转换为一个适合的应用传输(典型的是使用TBufferedTransportFactory)
(4) 使用TProtocolFactory,为TTransport创建一个输入和输出
(5) 创建TServer对象(单线程,可以使用TSimpleServer;对于多线程,用户可使用TThreadPoolServer或者TNonblockingServer),调用它的server()函数。
说明:thrift会为每一个带service的thrift文件生成一个简单的server代码(桩),
 
 
3.示例:
 

1. thrift生成代码

创建Thrift文件:G:\test\thrift\demoHello.thrift ,内容如下:

 
namespace java com.micmiu.thrift.demo
 
service  HelloWorldService {
  string sayHello(1:string username)
}
thrift-0.8.0.exe 是官网提供的windows下编译工具,运用这个工具生成相关代码:
thrift-0.8.0.exe -r -gen java ./demoHello.thrift
 
将生成的HelloWorldService.java 文件copy到自己测试的工程中,我的工程是用maven构建的,故在pom.xml中增加如下内容:
 
<dependency>
     <groupId>org.apache.thrift</groupId>
     <artifactId>libthrift</artifactId>
     <version>0.8.0</version>
</dependency>
<dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
     <version>1.5.8</version>
</dependency>
 

2. 实现接口Iface

java代码:HelloWorldImpl.java
 
package com.micmiu.thrift.demo;
import org.apache.thrift.TException;

public class HelloWorldImpl implements HelloWorldService.Iface {
     public HelloWorldImpl() {
     }
     @Override
     public String sayHello(String username) throws TException {
          return "Hi," + username + " welcome to my blog www.micmiu.com";
     }
}

 

3.TSimpleServer服务端

简单的单线程服务模型,一般用于测试。

编写服务端server代码:HelloServerDemo.java
 
package com.micmiu.thrift.demo;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TSimpleJSONProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;

public class HelloServerDemo {
     public static final int SERVER_PORT = 8090;
     public void startServer() {
          try {
               System.out.println("HelloWorld TSimpleServer start ....");
               TProcessor tprocessor = new HelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(
                         new HelloWorldImpl());
               // HelloWorldService.Processor&lt;HelloWorldService.Iface&gt; tprocessor =
               // new HelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(
               // new HelloWorldImpl());
               // 简单的单线程服务模型,一般用于测试
               TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
               TServer.Args tArgs = new TServer.Args(serverTransport);
               tArgs.processor(tprocessor);
               tArgs.protocolFactory(new TBinaryProtocol.Factory());
               // tArgs.protocolFactory(new TCompactProtocol.Factory());
               // tArgs.protocolFactory(new TJSONProtocol.Factory());
               TServer server = new TSimpleServer(tArgs);
               server.serve();
          } catch (Exception e) {
               System.out.println("Server start error!!!");
               e.printStackTrace();
          }
     }
     /**
     * @param args
     */
     public static void main(String[] args) {
          HelloServerDemo server = new HelloServerDemo();
          server.startServer();
     }
}

 
编写客户端Client代码:HelloClientDemo.java
 
package com.micmiu.thrift.demo;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;

public class HelloClientDemo {
     public static final String SERVER_IP = "localhost";
     public static final int SERVER_PORT = 8090;
     public static final int TIMEOUT = 30000;
     /**
     *
     * @param userName
     */
     public void startClient(String userName) {
          TTransport transport = null;
          try {
               transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
               // 协议要和服务端一致
               TProtocol protocol = new TBinaryProtocol(transport);
               // TProtocol protocol = new TCompactProtocol(transport);
               // TProtocol protocol = new TJSONProtocol(transport);
               HelloWorldService.Client client = new HelloWorldService.Client(
                         protocol);
               transport.open();
               String result = client.sayHello(userName);
               System.out.println("Thrify client result =: " + result);
          } catch (TTransportException e) {
               e.printStackTrace();
          } catch (TException e) {
               e.printStackTrace();
          } finally {
               if (null != transport) {
                    transport.close();
               }
          }
     }
     /**
     * @param args
     */
     public static void main(String[] args) {
          HelloClientDemo client = new HelloClientDemo();
          client.startClient("Michael");
     }
}

 

先运行服务端程序,日志如下:

 
HelloWorld TSimpleServer start ....

再运行客户端调用程序,日志如下:

 
Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com

测试成功,和预期的返回信息一致。

 
 
总结:Server端和client端编码基本步骤
 

1.服务端编码基本步骤:

  • 实现服务处理接口impl
  • 创建TProcessor
  • 创建TServerTransport
  • 创建TProtocol
  • 创建TServer
  • 启动Server

2.客户端编码基本步骤:

  • 创建Transport
  • 创建TProtocol
  • 基于TTransport和TProtocol创建 Client
  • 调用Client的相应方法
 
 
参考资料:http://www.micmiu.com/soa/rpc/thrift-sample/
               http://dongxicheng.org/search-engine/thrift-rpc/
               

使用Thrift RPC编写程序(服务端和客户端)的更多相关文章

  1. php编写TCP服务端和客户端程序

    1.修改php.ini,打开extension=php_sockets.dll 2.服务端程序SocketServer.php <?php //确保在连接客户端时不会超时 set_time_li ...

  2. swoole创建TCP服务端和客户端

    服务端: server.php <?php //创建Server对象,监听 127.0.0.1:9501端口    $serv = new swoole_server("127.0.0 ...

  3. 在python中编写socket服务端模块(二):使用poll或epoll

    在linux上编写socket服务端程序一般可以用select.poll.epoll三种方式,本文主要介绍使用poll和epoll编写socket服务端模块. 使用poll方式的服务器端程序代码: i ...

  4. C# 编写WCF简单的服务端与客户端

    http://www.wxzzz.com/1860.html Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Win ...

  5. Socket聊天程序——服务端

    写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: ...

  6. python thrift 服务端与客户端使用

    一.简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, ...

  7. java实现微信小程序服务端(登录)

    微信小程序如今被广泛使用,微信小程序按照微信官网的定义来说就是: 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验. 这就是微信小程序的魅力所在,有 ...

  8. 基于Select模型的Windows TCP服务端和客户端程序示例

    最近跟着刘远东老师的<C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台)>,Bilibili视频地址为C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台),重新复习下 ...

  9. [C语言]一个很实用的服务端和客户端进行TCP通信的实例

    本文给出一个很实用的服务端和客户端进行TCP通信的小例子.具体实现上非常简单,只是平时编写类似程序,具体步骤经常忘记,还要总是查,暂且将其记下来,方便以后参考. (1)客户端程序,编写一个文件clie ...

随机推荐

  1. 对Java“一切皆对象”的理念的理解

    在从HelloWorld到面向对象中,我们将int, float, double, boolean等称为基本类型(primitive type),也就是特殊的类.我们可以将一个整数理解称为一个int类 ...

  2. 《OD学hadoop》第四周0716

    7.16 一.回顾 二.HDFS Federation(联盟) Hadoop 2.2.0发布新特性 很多的大公司都在使用:BAT HDFS Federation + HDFS HA架构 互相隔开,但是 ...

  3. Ajax的简单请求案例

    $.ajax({ url : rootPath +'/jasframework/choosepilecontrol/querySubsytem.do', type : "POST" ...

  4. 基于UltraVNC实现客户端远程控制

    前言 一般远程就直接用windows自带的,配置好动态IP花生壳,在任何地方都可以连回机子.最近项目里遇到这么个情况,需要快速接入远程控制功能,客户机的IP每次都会变,并且都是在外网,这样,就必须使用 ...

  5. cookie随便写的一点笔记(抄书的)

    cookie是保存在客户端的文本,能够在一定程度上提高用户体验.Servlet API 中提供了Cookie类,可以创建Cookie对象,并通过响应中的addCookie方法,将cookie保存到客户 ...

  6. [反汇编练习] 160个CrackMe之022

    [反汇编练习] 160个CrackMe之022. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  7. Java 直线、多段线画板 PaintJFrame (整理)

    package demo; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; impor ...

  8. Android堆栈分析

    在开发中,与界面跳转联系比较紧密的概念是Task(任务)和Back Stack(回退栈).activity的启动模式会影响Task和Back Stack的状态, 进而影响用户体验.除了启动模式之外,I ...

  9. html:唤起手机qq开始对话 & 自动拨号

    <a href="mqqwpa://im/chat?chat_type=wpa&uin=[qq号]&version=1">XXX</a> 另 ...

  10. Symfony2 学习笔记之内部构件

    Symfony2内部是怎样工作的以及我们如何来扩展它呢?从外部整体上看,symfony2代码是由许多独立的层构成,每一层都是建立在前一层基础之上.其中,自动加载时不受框架直接管理的,它完全是在Univ ...