thrift 试用

 

5月底的业余时间试用了一下thrift,效果不错,今天在博客小记一下。
thrift主要是用来进行跨语言层的rpc服务框架,基本原理是通过.thrift 文件以及dsl来生成相应的语言代码,目前支持的语言:c++,c#,java,php,服务器与客户端连接使用tcp/ip,数据协议支持二进制,json等。
 
我实验的平台是c#语言做客户端,java做服务端。
 
因为thrift是基于代码生成,所以首先要来编写用于代码生成的.thrift ,对于客户端和服务端而言,.thrift 只需要编写一次即可,通过thrift 的生成程序 可以分别生成用于客户端的c#以及服务端的java。(我这里用c#做客户端,java做服务端).
 
thrift 支持常见的数据类型如下:
 
1.基本类型(对应java类型)
bool  对应 boolean
byte  对应 byte 8位
i16 对应 short  16位
i32 对应  int  32位
i64 对应 long  64位
double 对应 double64位
string 对应 String utf-8
 
2.特殊类型 :
 
binary 对应 ByteBuffer
 
3.Structs(结构):
 
注意每个field前面需要加入序号,语句结尾要加","。
 

 

struct test{
1:i32 id,
2:string name,
}
 
4.容器类型:
 
list<t>                   对应  List<t>
map<t1,t2>          对应   Map<t1,t2>
set<t>            对应  Set<t>
 
4.Include (包含):
 

 

include "product.thrift"  
 
list<product> getProductList();
 
我建立的.thrift 如下
 

 

 namespace java service.demo 
 
  
 struct Product{
  1:i32 id,
  2:string productName,
  3:string productNumber,
 
 }
 
 service Hello{ 
 //bean测试
  i32 testInt(1:i32 para)
  string testString(1:string para);
  double testDouble(1:double para);
  i64 testLong(1:i64 para);
  bool testBoolean(1:bool para);
  void testVoid();
  void testMultiPara(1:i32 para1,2:double para2,3:bool para3);
  
  //复杂实体测试
  void addModel(1:Product para,2:i32 para2);
  list<Product> getProductlList(1:i32 para);
  set<Product> getProductSet(1:i32 para);
  map<i32,Product> getProductMap(1:i32 para);
  
 }

 

 
按照下面语句格式生成相应平台代码
 
生成c# 
D:\杭州准备\thrift\thrift-0.9.0.exe -r -gen csharp D:\java\app\labs\src\thiftdemo\Test.thift
 
生成java
D:\杭州准备\thrift\thrift-0.9.0.exe -r -gen java D:\java\app\labs\src\thiftdemo\Test.thift
 
这里cshape 用来做客户端,java 做服务端
 
 
java 服务端 生成的文件为Hello.Iface ,建立一个类来继承并实现thrift加入的方法即可。
 
 
java 务端 :
package thiftdemo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
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 org.apache.thrift.transport.TTransportException;

public class HelloServer {
    public void open()
    {
        try {
            TServerSocket serverSocket = new TServerSocket( 9091 );

/* 使用二进制 */
            Factory factory = new TBinaryProtocol.Factory();

            TProcessor    processor    = new Hello.Processor( new HelloImpl() );
            Args        args        = new Args( serverSocket );
            args.processor( processor );

            args.protocolFactory( factory );

            TServer server = new TThreadPoolServer( args );

            System.out.println( "Start Thrift Port 9091" );
            server.serve();
        } catch ( TTransportException e ) {
/* TODO: handle exception */
        }
    }


    public static void main( String[] args )
    {
        HelloServer server = new HelloServer();
        server.open();
    }
}

 

 
 
 
java服务端业务:
package thiftdemo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.thrift.TException;

public class HelloImpl implements Hello.Iface {
    @Override
    public Product addProduct( Product para, int para2 ) throws TException
    {
        Product product = new Product();
        product.setId( 1 );
        product.setProductName( "test" );
        product.setProductNumber( "20130529" );
        return(product);
    }


    @Override
    public Map<Integer, Product> getProductMap( int para ) throws TException
    {
        Map<Integer, Product> map = new LinkedHashMap<Integer, Product>();

        for ( int i = 0; i < 10; i++ )
        {
            map.put( i, new Product( i, "test", "20130529" ) );
        }

        return(map);
    }


    @Override
    public Set<Product> getProductSet( int para ) throws TException
    {
        Set<Product> set = new LinkedHashSet<Product>();

        for ( int i = 0; i < 10; i++ )
        {
            set.add( new Product( i, "test", "20130529" ) );
        }

        return(set);
    }


    @Override
    public List<Product> getProductlList( int para ) throws TException
    {
        List<Product> productList = new ArrayList<Product>();

        for ( int i = 0; i < 10; i++ )
        {
            productList.add( new Product( i, "test", "20130529" ) );
        }

        return(productList);
    }


    @Override
    public boolean testBoolean( boolean para ) throws TException
    {
        return(para);
    }


    @Override
    public double testDouble( double para ) throws TException
    {
        return(para);
    }


    @Override
    public int testInt( int para ) throws TException
    {
        return(para);
    }


    @Override
    public long testLong( long para ) throws TException
    {
        return(para);
    }


    @Override
    public void testMultiPara( int para1, double para2, boolean para3 )
    throws TException
    {
    }


    @Override
    public String testString( String para ) throws TException
    {
        return(para);
    }


    @Override
    public void testVoid() throws TException
    {
    }
}

 

 
 
c# 客户端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thrift.Transport;
using Thrift.Protocol;
using NUnit.Framework;

namespace ThriftDemo
{
    [TestFixture]
    public class Client
    {
        private Hello.Client    client;
        private TTransport    transport;
        public Client()
        {
            this.Connect();
        }


        public void Connect()
        {
            this.transport = new TSocket( "127.0.0.1", 9091 );
            TProtocol protocol = new TBinaryProtocol( transport );
            this.client = new Hello.Client( protocol );
        }


        private void Open()
        {
            if ( !this.transport.IsOpen )
                this.transport.Open();
        }


        private void Close()
        {
            if ( this.transport.IsOpen )
                this.transport.Close();
        }


        [Test]
        public void TestInt()
        {
            this.Open();
            Assert.AreEqual( 3, this.client.testInt( 3 ) );

            this.Close();
        }


        [Test]
        public void TestString()
        {
            this.Open();
            Assert.AreEqual( "test", this.client.testString( "test" ) );
            this.Close();
        }


        [Test]
        public void TestLong()
        {
            this.Open();
            Assert.AreEqual( 3L, this.client.testLong( 3L ) );
            this.Close();
        }


        [Test]
        public void TestDouble()
        {
            this.Open();
            Assert.AreEqual( 3.5d, this.client.testDouble( 3.5d ) );
            this.Close();
        }


        [Test]
        public void TestBoolean()
        {
            this.Open();
            Assert.AreEqual( true, this.client.testBoolean( true ) );
            this.Close();
        }


        [Test]
        public void TestMultiPara()
        {
            this.Open();
            this.client.testMultiPara( 1, 1D, true );
            this.Close();
        }


        [Test]
        public void TestAddProduct()
        {
            this.Open();
            Product product = new Product();
            product.Id        = 1;
            product.ProductName    = "test";
            product.ProductNumber    = "20130529";
            Product productFromServer = this.client.addProduct( product, 1 );

            Assert.AreEqual( product.Id, productFromServer.Id );
            Assert.AreEqual( product.ProductName, productFromServer.ProductName );
            Assert.AreEqual( product.ProductNumber, productFromServer.ProductNumber );

            this.Close();
        }


        [Test]
        public void TestGetProductlList()
        {
            this.Open();
            List<Product> productList = this.client.getProductlList( 1 );
            Assert.AreEqual( productList.Count, 10 );

            this.Close();
        }


        [Test]
        public void TestGetProductSet()
        {
            this.Open();
            Thrift.Collections.THashSet<Product> productSet = this.client.getProductSet( 1 );
            Assert.AreEqual( productSet.Count, 10 );
            this.Close();
        }


        [Test]
        public void TestGetProductMap()
        {
            this.Open();
            Dictionary<int, Product> productHash = this.client.getProductMap( 1 );
            Assert.AreEqual( productHash.Count, 10 );

            Assert.AreEqual( productHash[0].Id, 0 );
            Assert.AreEqual( productHash[1].ProductName, "test" );
            Assert.AreEqual( productHash[2].ProductNumber, "20130529" );
            this.Close();
        }


        public static void Main( String[] args )
        {
            Client client = new Client();
            client.TestAddProduct();
        }
    }
}

 

 
 
 

客户端测试结果

 
  

 

下一篇想写写thrift的原理分析
 
郑州 2013年6月6日 晴
posted @ 2013-06-06 14:05  gsralex  阅读(304)  评论(0编辑  收藏  举报