Thrift 示例 (转)

  转自:http://blog.csdn.net/lk10207160511/article/details/50450541

一、概述
Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。
Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。【来自百度百科】
官网地址:thrift.apache.org


二、下载依赖(Maven)
1、在pom.xml 中添加如下内容:
[html] view plain copy print?
<span style="white-space:pre">        </span><dependency>  
            <groupId>org.apache.thrift</groupId>  
            <artifactId>libthrift</artifactId>  
            <version>0.9.3</version>  
        </dependency>  
        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-log4j12</artifactId>  
            <version>1.7.12</version>  
        </dependency>  

三、基本概念以及实现步骤
 
1、数据传输协议

TBinaryProtocol : 二进制格式.  
TCompactProtocol : 压缩格式  
TJSONProtocol : JSON格式  
TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析  

注意:客户端和服务端的协议要一致。
2、服务端

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

3、客户端

创建Transport  
创建TProtocol  
基于TTransport和TProtocol创建 Client  
调用Client的相应方法  


四、实例
1、thrift文件创建,并在文件中定义需要的接口方法

namespace java com.jmust.thrift.demo  
  
service  HelloWorldService {  
  string sayHello(1:string username)  
}  
2、执行thrift-0.9.3.exe生成代码

thrift-0.9.3.exe -r -gen java ./demoHello.thrift  
3、创建一个服务maven项目(shrift-service),将生成的HelloWorldService.java文件复制到自己的项目中,利用maven打包成为bundle作为一个服务包,里面代码具体是什么样子的,我们不需要关心,到时候需要用到的地方,只需要把这个服务包引进去即可使用,下面看看我的pom.xml文件(把该开放出去的package开放出去,该引进来的package引进来)
[html] view plain copy print?
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
  
    <groupId>com.jmust.thrift</groupId>  
    <artifactId>thrift-service</artifactId>  
    <version>1.0.0</version>  
    <packaging>jar</packaging>  
  
    <name>thrift-service</name>  
    <url>http://maven.apache.org</url>  
  
    <properties>  
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    </properties>  
  
    <dependencies>  
        <dependency>  
            <groupId>junit</groupId>  
            <artifactId>junit</artifactId>  
            <version>3.8.1</version>  
            <scope>test</scope>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.thrift</groupId>  
            <artifactId>libthrift</artifactId>  
            <version>0.9.3</version>  
        </dependency>  
        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-log4j12</artifactId>  
            <version>1.7.12</version>  
        </dependency>  
    </dependencies>  
      
    <build>  
        <plugins>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-compiler-plugin</artifactId>  
                <version>2.3.2</version>  
                <configuration>  
                    <source>1.7</source>  
                    <target>1.7</target>  
                    <encoding>${project.build.sourceEncoding}</encoding>  
                </configuration>  
            </plugin>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-resources-plugin</artifactId>  
                <version>2.4.3</version>  
                <executions>  
                    <execution>  
                        <phase>compile</phase>  
                    </execution>  
                </executions>  
                <configuration>  
                    <encoding>${project.build.sourceEncoding}</encoding>  
                </configuration>  
            </plugin>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-source-plugin</artifactId>  
                <version>2.4</version>  
                <executions>  
                    <execution>  
                        <phase>deploy</phase>  
                        <goals>  
                            <goal>jar</goal>  
                        </goals>  
                    </execution>  
                </executions>  
            </plugin>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-deploy-plugin</artifactId>  
                <version>2.8.2</version>  
                <configuration>  
                    <skip>false</skip>  
                </configuration>  
            </plugin>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-javadoc-plugin</artifactId>  
                <version>2.10.3</version>  
                <configuration>  
                    <aggregate>true</aggregate>  
                </configuration>  
            </plugin>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-surefire-plugin</artifactId>  
                <version>2.7.2</version>  
                <configuration>  
                    <skip>false</skip>  
                </configuration>  
            </plugin>  
            <plugin>  
                <groupId>org.codehaus.mojo</groupId>  
                <artifactId>cobertura-maven-plugin</artifactId>  
                <version>2.7</version>  
            </plugin>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-jar-plugin</artifactId>  
                <version>2.3.1</version>  
                <configuration>  
                    <archive>  
                        <manifest>  
                            <addClasspath>true</addClasspath>  
                            <classpathPrefix>lib/</classpathPrefix>  
                        </manifest>  
                        <manifestEntries>  
                            <Class-Path>.</Class-Path>  
                            <Built-By>JMUST</Built-By>  
                            <Bundle-ManifestVersion>2</Bundle-ManifestVersion>  
                            <Bundle-Name>${project.groupId}.${project.ArtifactId}</Bundle-Name>  
                            <Bundle-SymbolicName>${project.groupId}.${project.ArtifactId}</Bundle-SymbolicName>  
                            <Bundle-Version>${project.version}</Bundle-Version>  
                            <Bundle-Vendor>${project.groupId}</Bundle-Vendor>  
                            <Export-Package>com.jmust.thrift.service;version=${project.version}  
                            </Export-Package>  
                            <Import-Package>  
                                javax.annotation,org.slf4j,org.apache.thrift,org.apache.thrift.async,org.apache.thrift.scheme,org.apache.thrift.protocol,org.apache.thrift.server.AbstractNonblockingServer  
                            </Import-Package>  
                        </manifestEntries>  
                    </archive>  
                </configuration>  
            </plugin>  
        </plugins>  
    </build>  
</project>  


4、再创建一个实现以上服务maven项目(thrift-demo),pom.xml文件只需要引入
[html] view plain copy print?
<span style="white-space:pre">        </span><dependency>  
            <groupId>org.apache.thrift</groupId>  
            <artifactId>libthrift</artifactId>  
            <version>0.9.3</version>  
        </dependency>  
        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-log4j12</artifactId>  
            <version>1.7.12</version>  
        </dependency>  
        <dependency>  
            <groupId>com.jmust.thrift</groupId>  
            <artifactId>thrift-service</artifactId>  
            <version>1.0.0</version>  
        </dependency>  

4.1、实现接口Iface
[java] view plain copy print?
package com.jmust.thrift.impl;  
  
import org.apache.thrift.TException;  
  
import com.jmust.thrift.service.HelloWorldService.Iface;  
  
/** 
 *  
 * @author LK 
 * 
 */  
public class HelloWorldImpl implements Iface  
{  
  
    public HelloWorldImpl(){  
          
    }  
      
    public String sayHello(String username) throws TException {  
        return "Hi," + username + " welcome to my blog www.jmust.com";  
    }  
     
}  


5、根据协议去实现服务端
5.1、TSimpleServer服务端-----简单的单线程服务模型,一般用于测试
[java] view plain copy print?
package com.jmust.thrift.demo;  
  
  
import org.apache.thrift.TProcessor;  
import org.apache.thrift.protocol.TBinaryProtocol;  
import org.apache.thrift.server.TServer;  
import org.apache.thrift.server.TServer.Args;  
import org.apache.thrift.server.TSimpleServer;  
import org.apache.thrift.transport.TServerSocket;  
  
import com.jmust.thrift.impl.HelloWorldImpl;  
import com.jmust.thrift.service.HelloWorldService.Iface;  
import com.jmust.thrift.service.HelloWorldService.Processor;  
  
/** 
 * 单线程服务模型,一般用于测试  TSimpleServer服务端 
 * @author LK 
 * 
 */  
public class HelloTSimpleServerDemo {  
  
    public static final int SERVER_PORT = 8090;  
  
    public void startServer() {  
        try {  
            System.out.println("HelloWorld TSimpleServer start ....");  
   
            TProcessor tprocessor = new Processor<Iface>(  
                    new HelloWorldImpl());  
            // 简单的单线程服务模型,一般用于测试    
            TServerSocket serverTransport = new TServerSocket(SERVER_PORT);  
            Args tArgs = new Args(serverTransport);  
            tArgs.processor(tprocessor);  
            tArgs.protocolFactory(new TBinaryProtocol.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) {  
        HelloTSimpleServerDemo server = new HelloTSimpleServerDemo();  
        server.startServer();  
    }  
}  

5.2、TThreadPoolServer 服务模型 ------线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求
[java] view plain copy print?
package com.jmust.thrift.demo;  
  
  
import org.apache.thrift.TProcessor;  
import org.apache.thrift.protocol.TBinaryProtocol;  
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 com.jmust.thrift.impl.HelloWorldImpl;  
import com.jmust.thrift.service.HelloWorldService.Iface;  
import com.jmust.thrift.service.HelloWorldService.Processor;  
  
/** 
 * 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求    TThreadPoolServer 服务模型 
 * @author LK 
 * 
 */  
public class HelloTThreadPoolServerDemo {  
  
    public static final int SERVER_PORT = 8090;  
      
    public void startServer() {  
        try {  
            System.out.println("HelloWorld TThreadPoolServer start ....");  
   
            TProcessor tprocessor = new Processor<Iface>(  
                    new HelloWorldImpl());  
            TServerSocket serverTransport = new TServerSocket(SERVER_PORT);  
            //TThreadPoolServer 线程池服务模型  
            Args ttpsArgs = new Args(  
                     serverTransport);  
            ttpsArgs.processor(tprocessor);  
            ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());  
            //线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。  
            TServer server = new TThreadPoolServer(ttpsArgs);  
            server.serve();  
        } catch (Exception e) {  
            System.out.println("Server start error!!!");  
            e.printStackTrace();  
        }  
    }  
   
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        HelloTThreadPoolServerDemo server = new HelloTThreadPoolServerDemo();  
        server.startServer();  
    }  
}  


5.3、TNonblockingServer 服务模型  -------使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式
[java] view plain copy print?
package com.jmust.thrift.demo;  
  
  
import org.apache.thrift.TProcessor;  
import org.apache.thrift.protocol.TCompactProtocol;  
import org.apache.thrift.server.TNonblockingServer;  
import org.apache.thrift.server.TNonblockingServer.Args;  
import org.apache.thrift.server.TServer;  
import org.apache.thrift.transport.TFramedTransport;  
import org.apache.thrift.transport.TNonblockingServerSocket;  
  
import com.jmust.thrift.impl.HelloWorldImpl;  
import com.jmust.thrift.service.HelloWorldService.Iface;  
import com.jmust.thrift.service.HelloWorldService.Processor;  
  
/** 
 * 使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式    TNonblockingServer 服务模型 
 * @author LK 
 * 
 */  
public class HelloTNonblockingServerDemo {  
  
    public static final int SERVER_PORT = 8090;  
    public void startServer() {  
        try {  
            System.out.println("HelloWorld TNonblockingServer start ....");  
   
            TProcessor tprocessor = new Processor<Iface>(  
                    new HelloWorldImpl());  
            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);  
            Args tnbArgs = new Args(tnbSocketTransport);  
            tnbArgs.processor(tprocessor);  
            tnbArgs.transportFactory(new TFramedTransport.Factory());  
            tnbArgs.protocolFactory(new TCompactProtocol.Factory());  
            TServer server = new TNonblockingServer(tnbArgs);  
            server.serve();  
              
        } catch (Exception e) {  
            System.out.println("Server start error!!!");  
            e.printStackTrace();  
        }  
    }  
   
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        HelloTNonblockingServerDemo server = new HelloTNonblockingServerDemo();  
        server.startServer();  
    }  
}  

5.4、THsHaServer服务模型  -------半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式
[java] view plain copy print?
package com.jmust.thrift.demo;  
  
  
import org.apache.thrift.TProcessor;  
import org.apache.thrift.protocol.TBinaryProtocol;  
import org.apache.thrift.server.THsHaServer;  
import org.apache.thrift.server.THsHaServer.Args;  
import org.apache.thrift.server.TServer;  
import org.apache.thrift.transport.TFramedTransport;  
import org.apache.thrift.transport.TNonblockingServerSocket;  
  
import com.jmust.thrift.impl.HelloWorldImpl;  
import com.jmust.thrift.service.HelloWorldService.Iface;  
import com.jmust.thrift.service.HelloWorldService.Processor;  
  
/** 
 * 半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式  THsHaServer服务模型 
 * @author LK 
 * 
 */  
public class HelloTHsHaServerDemo {  
  
    public static final int SERVER_PORT = 8090;  
    public void startServer() {  
        try {  
            System.out.println("HelloWorld THsHaServer start ....");  
   
            TProcessor tprocessor = new Processor<Iface>(  
                    new HelloWorldImpl());  
            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);  
            Args args = new Args(tnbSocketTransport);  
            args.processor(tprocessor);  
            args.transportFactory(new TFramedTransport.Factory());  
            args.protocolFactory(new TBinaryProtocol.Factory());  
            TServer server = new THsHaServer(args);  
            server.serve();  
              
        } catch (Exception e) {  
            System.out.println("Server start error!!!");  
            e.printStackTrace();  
        }  
    }  
   
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        HelloTHsHaServerDemo server = new HelloTHsHaServerDemo();  
        server.startServer();  
    }  
}  

6、客户端实现
6.1、同步
[java] view plain copy print?
package com.jmust.thrift.demo;  
  
import org.apache.thrift.TException;  
import org.apache.thrift.protocol.TBinaryProtocol;  
import org.apache.thrift.protocol.TProtocol;  
import org.apache.thrift.transport.TFramedTransport;  
import org.apache.thrift.transport.TSocket;  
import org.apache.thrift.transport.TTransport;  
import org.apache.thrift.transport.TTransportException;  
  
import com.jmust.thrift.service.HelloWorldService.Client;  
  
/** 
 *  
 * @author LK 
 * 
 */  
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);  
            transport = new TFramedTransport(new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT));  
            // 协议要和服务端一致  
            TProtocol protocol = new TBinaryProtocol(transport);  
            //TProtocol protocol = new TCompactProtocol(transport);  
            // TProtocol protocol = new TJSONProtocol(transport);  
            Client client = new 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("lvk");  
  
    }  
}  

6.2、异步
[html] view plain copy print?
package com.jmust.thrift.demo;  
  
import java.util.concurrent.CountDownLatch;  
import java.util.concurrent.TimeUnit;  
  
import org.apache.thrift.TException;  
import org.apache.thrift.async.AsyncMethodCallback;  
import org.apache.thrift.async.TAsyncClientManager;  
import org.apache.thrift.protocol.TCompactProtocol;  
import org.apache.thrift.protocol.TProtocolFactory;  
import org.apache.thrift.transport.TNonblockingSocket;  
import org.apache.thrift.transport.TNonblockingTransport;  
  
import com.jmust.thrift.service.HelloWorldService.AsyncClient;  
import com.jmust.thrift.service.HelloWorldService.AsyncClient.sayHello_call;  
  
/**  
 * 异步客户端  
 * @author LK  
 *  
 */  
public class HelloAsynClientDemo {  
    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) {  
        try {  
            TAsyncClientManager clientManager = new TAsyncClientManager();  
            TNonblockingTransport transport = new TNonblockingSocket(SERVER_IP, SERVER_PORT, TIMEOUT);  
            TProtocolFactory tprotocol = new TCompactProtocol.Factory();  
            AsyncClient asyncClient = new AsyncClient(tprotocol, clientManager, transport);  
            System.out.println("Client start .....");  
          
            CountDownLatch latch = new CountDownLatch(1);  
            AsynCallback callBack = new AsynCallback(latch);  
            System.out.println("call method sayHello start ...");  
            asyncClient.sayHello(userName, callBack);  
            System.out.println("call method sayHello .... end");  
            boolean wait = latch.await(30, TimeUnit.SECONDS);  
            System.out.println("latch.await =:" + wait);  
              
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("startClient end.");  
    }  
  
    public class AsynCallback implements AsyncMethodCallback<sayHello_call>{  
        private CountDownLatch latch;  
  
        public AsynCallback(CountDownLatch latch) {  
            this.latch = latch;  
        }  
        public void onComplete(sayHello_call response) {  
            System.out.println("onComplete");  
            try {  
                // Thread.sleep(1000L * 1);  
                System.out.println("AsynCall result =:"  
                        + response.getResult().toString());  
            } catch (TException e) {  
                e.printStackTrace();  
            } catch (Exception e) {  
                e.printStackTrace();  
            } finally {  
                latch.countDown();  
            }  
        }  
        public void onError(Exception exception) {  
            System.out.println("onError :" + exception.getMessage());  
            latch.countDown();  
        }  
    }  
    /**  
     * @param args  
     */  
    public static void main(String[] args) {  
        HelloAsynClientDemo client = new HelloAsynClientDemo();  
        client.startClient("lvk");  
    }  
}  

7.、测试步骤
先运行服务端,让后再运行客户端,看看是否输出预计结果。

猜你喜欢

转载自java12345678.iteye.com/blog/2374535
今日推荐