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. js学习之道:表单验证公共js

    /** 文件名称:CommonUtil.js 作者  : Yuce 编制时间: 2010-03-24 文件内容:一些常用的js公用类.工具类 包括方法: g_FormFieldIsNull    判断 ...

  2. Android判断网络是否已经连接

    // check all network connect, WIFI or mobile public static boolean isNetworkAvailable(final Context ...

  3. centos6.5 中文

    之前在网上查了不少资料,很多网友在网上都说,在shell命令下输入:     # vi  /etc/sysconfig/i18n     然后修改LANG="en_US.UTF-8" ...

  4. Python 数据类型转换

    Python提供的基本数据类型主要有:布尔类型.整型.浮点型.字符串.列表.元组.集合.字典.日期等等 函数                      描述     type(x)  x的数据类型   ...

  5. [51NOD1087]1 10 100 1000(规律,二分)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1087 用高中的数列知识就可以推出公式,不难发现f(n)=f(n ...

  6. Hadoop集群(第3期)_VSFTP安装配置

    1.VSFTP简介 VSFTP是一个基于GPL发布的类Unix系统上使用的FTP服务器软件,它的全称是Very Secure FTP 从此名称可以看出来,编制者的初衷是代码的安全. 安全性是编写VSF ...

  7. 【Todo】Java Queue Stack Vector ArrayList

    Java集合框架里存在Queue这个接口,之后有不同类型的队列的实现. 有Stack这个类实现堆栈,其实这个类是通过继承Vector的方式来实现的, Vector和ArrayList的实现方式差不多, ...

  8. Android实现图片裁切

    介绍 在应用开发中,如果涉及到个人信息,头像一般是不可避免的,类似这种情况,我们就需要用到图片裁切的功能,实现头像裁切,然后上传给服务器. 一般裁切的做法就是图层叠加选取框,然后根据坐标,计算裁切区域 ...

  9. orm 通用方法——GetOneModel 条件查询一个对象

    数据连接层的方法封装成通用方法是很有必要,节省不必要的重复写代码. Golang的orm.xorm框架没有封装这些操作. 这里是一个查询单个对象的方法. 此处抛砖引玉,大家继续完善. 通用方法定义代码 ...

  10. codeVS1966 乘法游戏

    区间dp. 用f[l][r]代表从l合并到r的最小得分. 显然 r-l<=1时,f[l][r]=0. 对区间dp一直很不熟悉,得多练练了. #include<cstdio> #inc ...