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. 手持机连不上信道设置为13的AP

    这个是正常的, 因为每个国家的CHANNEL 都不一样, 中国和美国都只支持 CHANNEL 1- 11  欧洲会到 12, 13 channal , 日本会到CHANNEL 14 . "O ...

  2. 了解ThinkPHP(一)

    1.项目开发,中,会遇到的问题: 1). 多人开发项目,分工不合理,(html   php   mysql) 2). 代码风格不一样,后期维护十分困难 3). 项目生命周期十分短,项目生命没有延续性, ...

  3. mysql 字符串函数

    对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的 最左面字符的ASCII代码值.如果str是空字符串, 返回0.如果str是NULL,返回NULL. mysq ...

  4. pl/sql programming 05 循环迭代处理

    使用循环应考虑的因素 1. 循环什么时候结束 2. 什么时候测试是否该结束循环 3. 采用这种循环的原因 1. 普通循环(简单循环) 使用场合, 不能确定循环执行多少次, 要求循环至少执行一次. 另外 ...

  5. C#克隆实例详解

    public AtmDataBase DeepClone() { MemoryStream ms = new MemoryStream(); BinaryFormatter bf = new Bina ...

  6. Qt之设置QWidget背景色

    简述 QWidget是所有用户界面对象的基类,这意味着可以用同样的方法为其它子类控件改变背景颜色. Qt中窗口背景的设置,下面介绍三种方法. 使用QPalette 使用Style Sheet 绘图事件 ...

  7. eclipse中字母大小写转换快捷键

    ctrl+shift+x   转为大写 ctrl+shift+y   转为小写

  8. CodeForces ZeptoLab Code Rush 2015

    拖了好久的题解,想想还是补一下吧. A. King of Thieves 直接枚举起点和5个点之间的间距,进行判断即可. #include <bits/stdc++.h> using na ...

  9. 【第六篇】javascript显示当前的时间(年月日 时分秒 星期)

    不多说自己上代码 这是我开始学javascript写的,现在发出来 <span id="clock" ></span> function time() { ...

  10. web项目路径问题

    路径    相对路径        URL中第一个字符不为“/”        request.getRequestDispatcher("b");        相对于该代码所在 ...