MangoCool

一个简单的Thrift框架Java语言示例

2015-09-07 11:49:53   作者:MangoCool   来源:MangoCool

Apache Thrift 是 Facebook 实现的一种高效的、支持多种编程语言的远程服务调用的框架。本文将从 Java 开发人员角度编写一个超级简单也极富有代表性的 Java 实例,通过本文的学习能基本掌握Thrift的开发和使用。

软件:Thrift-0.9.2

依赖:jdk1.7

开发环境:ideaIU-14.1.4

测试环境:win7

Thrift-0.9.2下载地址:http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.2/thrift-0.9.2.exe

建立maven工程ThriftDemo,在pom.xml配置文件添加必要的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<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>ThriftDemo</groupId>
    <artifactId>ThriftDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.9.2</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>

    </dependencies>

</project>

根据 Thrift 的语法规范编写脚本文件 UserService.thrift:

namespace java com.mangocool.thrift

struct User
{
    1:string id
    2:string name
    3:i32 sex
}

service UserService
{
    string whatIsName(1:string word)
    User userInfo(1:string id)
}

namespace:命名空间。

java:生成的RPC代码的开发语言种类,以便用户可以在自己的程序中调用。

com.mangocool.thrift:生成代码的包路径。

struct:自定义公共对象,就是java中的JavaBean,以便在后续定义的接口方法中使用。

service:对应服务的类,类中定义了RPC接口。

通过Thrift编译工具生成对应接口文件和自定义结构:

thrift --gen <language> <Thrift filename>
我的命令:
D:\>thrift-0.9.2.exe --gen java D:\ThriftDemo\src\main\resources\UserService.thrift

编译生成的User.java和UserService.java,这里就不贴了。

实现类UserServiceImpl.java:

package com.mangocool.thrift;

import org.apache.thrift.TException;

/**
 * Created by MANGOCOOL on 2015/9/7.
 */
public class UserServiceImpl implements UserService.Iface
{

    @Override
    public String whatIsName(String word) throws TException {
        String name = "what talking about?";
        if(!word.isEmpty())
        {
            name = "my name is mangocool!";
        }
        System.out.println("接收的参数word: " + word);
        return name;
    }

    @Override
    public User userInfo(String id) throws TException {
        User user = new User();
        if(!id.isEmpty() && id.equals("1023"))
        {
            user.setId("1023");
            user.setName("mangocool");
            user.setSex(1);
        } else
        {
            user.setName("no user!");
        }
        System.out.println("接收的参数id: " + id);
        return user;
    }
}

客户端UserServiceClient.java:

package com.mangocool.thrift;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransportException;

/**
 * Created by MANGOCOOL on 2015/9/7.
 */
public class UserServiceClient {

    public void start()
    {
        String compAddress="localhost";
        int port=7911;
        int timeout=100*1000;
        //使用非阻塞方式,按块的大小进行传输,类似于Java中的NIO
        TFramedTransport transport =
                new TFramedTransport(new TSocket(compAddress, port, timeout));
        //高效率的、密集的二进制编码格式进行数据传输协议
        TProtocol protocol = new TCompactProtocol(transport);
        UserService.Client client = new UserService.Client(protocol);
        try {
            open(transport);
            System.out.println(client.whatIsName(""));
            System.out.println(client.whatIsName("hello!"));
            System.out.println(client.userInfo(""));
            System.out.println(client.userInfo("1023"));
            close(transport);
        } catch (TException e) {
            e.printStackTrace();
        }
    }

    public void open(TFramedTransport transport)
    {
        if(transport != null && !transport.isOpen())
        {
            try {
                transport.open();
            } catch (TTransportException e) {
                e.printStackTrace();
            }
        }
    }

    public void close(TFramedTransport transport)
    {
        if(transport != null && transport.isOpen())
        {
            transport.close();
        }
    }

    public static void main(String[] args) {
        UserServiceClient usc = new UserServiceClient();
        usc.start();
    }
}

服务端UserServiceServer.java:

package com.mangocool.thrift;

import org.apache.thrift.TProcessor;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TNonblockingServerTransport;
import org.apache.thrift.transport.TTransportException;

/**
 * Created by MANGOCOOL on 2015/9/7.
 */
public class UserServiceServer {

    private int servicePort = 7911;

    public void invoke()
    {
        try {
            //非阻塞式的,配合TFramedTransport使用
            TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(servicePort);
            //关联处理器与Service服务的实现
            TProcessor processor = new UserService.Processor<UserService.Iface>(new UserServiceImpl());
            //继承了TNonblockingServer,可同时提供非阻塞方式同步(TFramedTransport)和异步(TNonblockingTransport)的服务
            THsHaServer.Args args = new THsHaServer.Args(serverTransport);
            args.processor(processor);
            //设置协议工厂,高效率的、密集的二进制编码格式进行数据传输协议
            args.protocolFactory(new TCompactProtocol.Factory());
            //设置传输工厂,使用非阻塞方式,按块的大小进行传输,类似于Java中的NIO
            args.transportFactory(new TFramedTransport.Factory());
            //设置处理器工厂,只返回一个单例实例
            args.processorFactory(new TProcessorFactory(processor));
            TServer server = new TNonblockingServer(args);
            System.out.println("Starting server on port " + servicePort + "......");
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        UserServiceServer uss = new UserServiceServer();
        uss.invoke();
    }
}

先启动UserServiceServer,在运行UserServiceClient,输出结果分别为:

客户端:

what talking about?
my name is mangocool!
User(id:null, name:no user!, sex:0)
User(id:1023, name:mangocool, sex:1)
服务端:
Starting server on port 7911......
接收的参数word: 
接收的参数word: hello!
接收的参数id: 
接收的参数id: 1023

到此本文就已结束,有不对或是不完善地方请多多指正以及多多谅解!


参考文章:http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/

                http://roclinux.cn/?p=3316

标签: Thrift Java Demo

分享:

上一篇阻塞、非阻塞与同步、异步的区别,看过之后一定能懂

下一篇Error:java: Compilation failed: internal java compiler error

关于我

崇尚极简,热爱技术,喜欢唱歌,热衷旅行,爱好电子产品的一介码农。

座右铭

当你的才华还撑不起你的野心的时候,你就应该静下心来学习,永不止步!

人生之旅历途甚长,所争决不在一年半月,万不可因此着急失望,招精神之萎葸。

Copyright 2015- 芒果酷(mangocool.com) All rights reserved. 湘ICP备14019394号

免责声明:本网站部分文章转载其他媒体,意在为公众提供免费服务。如有信息侵犯了您的权益,可与本网站联系,本网站将尽快予以撤除。