`
liyonghui160com
  • 浏览: 775976 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

 

讲述一下如何使用Thrift搭建C#版的客户端以及服务端通讯的程序

 

1. 先从官网下载Thrift安装包以及签出SVN源码:

官网下载地址:http://thrift.apache.org/download/

这里我下载了一个Thrift compiler for Windows版本的EXE文件(thrift-0.7.0.exe)

签出SVN源码地址:http://svn.apache.org/repos/asf/thrift/trunk

 

2. 首先创建脚本,命名为textCsharp.thrift,脚本内容如下:

namespace java com.javabloger.gen.code   #  注释1
namespace csharp com.javabloger.gen.code   #  注释1
namespace cpp com.javabloger.gen.code
namespace perl com.javabloger.gen.code
namespace php com.javabloger.gen.code
struct Blog {   #  注释2 
    1: string topic 
    2: binary content 
    3: i64    createdTime 
    4: string id 
    5: string ipAddress 
    6: map<string,string> props 
  }


service ThriftCase {  #  注释3 
    i32 testCase1(1:i32 num1, 2:i32 num2, 3:string  num3)  #  注释4

    list<string> testCase2(1:map<string,string>  num1)

    void testCase3()

   void testCase4(1:list<Blog> blog)  
}
 
    类型 描述
    bool truefalse
    byte 8位的有符号整数
    i16 16位的有符号整数
    i32 32位的有符号整数
    i64 64位的有符号整数
    double 64位的浮点数
    string UTF-8编码的字符串
    binary 字符数组
    struct 结构体
    list 有序的元素列表,类似于STL的vector
    set 无序的不重复元素集,类似于STL的set
    map key-value型的映射,类似于STL的map
    exception 是一个继承于本地语言的exception基类
    service 服务。包含多个函数接口(纯虚函数)
3. 执行thrift命令:thrift -gen csharp testCsharp.thrift,这里说明一下:参数"csharp”意味着这里将自动生成C#代码,如果这里写java,python等等,可以用"java"或者"py”代替。
     thrift-0.7.0.exe   -r   -gen  java    TestThrift.thrift    生成java 代码
     thrift-0.7.0.exe   -r   -gen  php    TestThrift.thrift    生成php代码
     thrift-0.7.0.exe   -r   -gen  py       TestThrift.thrift    生成python代码
     thrift-0.7.0.exe   -r   -gen  as3     TestThrift.thrift    生成as3代码
     thrift-0.7.0.exe   -r   -gen  cpp     TestThrift.thrift    生成C++代码
于是得到gen-csharp的目录,这个目录里面就包含支持Thrift的Blog以及ThriftCase的源代码,具体里面都生成什么代码,后面会做出介绍。
4.然后,我现在打开SVN源码中的 trunk\lib\csharp\ 路径,我用项目打开,编译后,得到Thrift.dll文件,为了后面使用Thrift做准备。
5.新建工程,添加Server以及Client项目,把刚才生成的代码文件放入Common项目中。让Client和Server项目引用Thrift.dll类库。

 
6.编写服务端程序:
public class Server 
{ 
    public void Start() 
    { 
        TServerSocket serverTransport = new TServerSocket(7911, 0, false); 
        ThriftCase.Processor processor = new ThriftCase.Processor(new BusinessImpl()); 
        TServer server = new TSimpleServer(processor, serverTransport); 
        Console.WriteLine("Starting server on port 7911 ..."); 
        server.Serve(); 
    } 
} 
 
其中BusinessImpl具体提供业务逻辑的实现:
public class BusinessImpl : ThriftCase.Iface 
    { 
        public int testCase1(int num1, int num2, String num3) 
        { 
             int i = num1 + num2; 
             Console.Write( "testCase1  num1+num2 is :"+ i); 
            Console.WriteLine( "   num3 is :"+ num3); 
             return i; 
        }

        public List<String> testCase2(Dictionary<String, String> num1) 
        { 
            Console.WriteLine("testCase2 num1 :" + num1); 
            List<String> list = new List<String>(); 
            list.Add("num1"); 
            return list; 
        }

        public void testCase3() 
        { 
            Console.WriteLine("testCase3 ..........." + DateTime.Now); 
        }

        public void testCase4(List<Blog> blogs) 
        { 
            Console.WriteLine("testCase4 ..........."); 
        
            for (int i = 0; i < blogs.Count; i++) 
            { 
                Blog blog = blogs[i]; 
                Console.Write("id:" + blog.Id); 
                Console.Write(",IpAddress:" + blog.IpAddress); 
                //Console.Write (",Content:" + new String(blog.Content)); 
                Console.Write(",topic:" + blog.Topic); 
                Console.Write(",time:" + blog.CreatedTime); 
            } 
            Console.WriteLine("\n"); 
        } 
    }
 
7. 编写客户端程序:
class Client 
    { 
        static Dictionary<String, String> map = new Dictionary<String, String>(); 
        static List<Blog> blogs = new List<Blog>();

        static void Main(string[] args) 
        { 
            TTransport transport = new TSocket("localhost", 7911); 
            TProtocol protocol = new TBinaryProtocol(transport); 
            ThriftCase.Client client = new ThriftCase.Client(protocol); 
            transport.Open(); 
            Console.WriteLine("Client calls ....."); 
            map.Add("blog", "http://www.javabloger.com%22);/

            client.testCase1(10, 21, "3"); 
            client.testCase2(map); 
            client.testCase3();

            Blog blog = new Blog(); 
            //blog.setContent("this is blog content".getBytes()); 
            blog.CreatedTime = DateTime.Now.Ticks; 
            blog.Id = "123456"; 
            blog.IpAddress = "127.0.0.1"; 
            blog.Topic = "this is blog topic"; 
            blogs.Add(blog); 
            
            client.testCase4(blogs); 
            
            transport.Close();

            Console.ReadKey(); 
        } 
    }
 
8.先运行Server在运行Client。

9.补充java实现
创建服务
1创建user.thrift

 
   namespace java thrift.demo.gen 
    namespace py thrift.demo 
    struct User{ 
        1: i32 id, 
        2: string username, 
        3: string password 
    } 
     
    exception UserNotFound{ 
        1:string message 
    } 
     
    service UserService{ 
        list<User> getUsers(), 
        User getUserByName(1:string username) throws(1:UserNotFound unf) 
    }  
 


定义了一个User ,一个UerNotFound异常,一个UserService服务接口

 

注意定义的时候 序号是不可省略的,使用序号可以提升序列化和反序列对象的速度。



2.生成代码
生成java代码:thrift-0.6.1.exe --gen java  user.thrift 


3.实现服务端
3.1接口服务实现

   
package thrift.demo.server; 
     
    import java.util.ArrayList; 
    import java.util.List; 
     
    import org.apache.thrift.TException; 
     
    import thrift.demo.gen.User; 
    import thrift.demo.gen.UserNotFound; 
    import thrift.demo.gen.UserService.Iface; 
     
    public class UserServiceHandler implements Iface { 
     
        @Override 
        public List<User> getUsers() throws TException { 
            List<User> list = new ArrayList<User>(); 
            User user = new User(); 
            user.setId(1); 
            user.setUsername("user1"); 
            user.setPassword("pwd1"); 
            list.add(user); 
            User user2 = new User(); 
            user2.setId(1); 
            user2.setUsername("user2"); 
            user2.setPassword("pwd2"); 
            list.add(user2); 
            return list; 
        } 
     
        @Override 
        public User getUserByName(String username) throws UserNotFound, TException { 
            if ("user1".equals(username)) { 
                User user = new User(); 
                user.setId(1); 
                user.setUsername("user1"); 
                user.setPassword("pwd1"); 
                return user; 
            } else { 
                throw new UserNotFound(); 
            } 
        } 
     
    }  
 

3.2 Server启动类

   
package thrift.demo.server; 
     
    import org.apache.thrift.TProcessorFactory; 
    import org.apache.thrift.protocol.TCompactProtocol; 
    import org.apache.thrift.server.THsHaServer; 
    import org.apache.thrift.server.TServer; 
    import org.apache.thrift.transport.TFramedTransport; 
    import org.apache.thrift.transport.TNonblockingServerSocket; 
    import org.apache.thrift.transport.TTransportException; 
     
    import thrift.demo.gen.UserService; 
     
    public class UserServer { 
     
        public final static int PORT = 8989; 
        /**
         * @param args
         */ 
        public static void main(String[] args) { 
            try { 
                TNonblockingServerSocket socket = new TNonblockingServerSocket(PORT); 
                final UserService.Processor processor = new UserService.Processor( 
                        new UserServiceHandler());  
                THsHaServer.Args arg = new THsHaServer.Args(socket); 
                arg.protocolFactory(new TCompactProtocol.Factory()); 
                arg.transportFactory(new TFramedTransport.Factory()); 
                arg.processorFactory(new TProcessorFactory(processor)); 
                TServer server = new THsHaServer(arg); 
                server.serve(); 
            } catch (TTransportException e) { 
                e.printStackTrace(); 
            } 
             
     
        } 
     
    }  
 



4.实现客户端

   
package thrift.demo.client; 
     
    import org.apache.thrift.TApplicationException; 
    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.TSocket; 
    import org.apache.thrift.transport.TTransport; 
    import org.apache.thrift.transport.TTransportException; 
     
    import thrift.demo.gen.UserNotFound; 
    import thrift.demo.gen.UserService; 
     
    public class UserClient { 
        public static void main(String[] arsg) { 
     
            String address = "127.0.0.1"; 
            int port = 8989; 
            int clientTimeout = 30000; 
            TTransport transport = new TFramedTransport(new TSocket(address, port, 
                    clientTimeout)); 
            TProtocol protocol = new TCompactProtocol(transport); 
            UserService.Client client = new UserService.Client(protocol); 
     
            try { 
                transport.open(); 
                System.out.println(client.getUserByName("user1")); 
     
            } catch (TApplicationException e) { 
                System.out.println(e.getMessage() + " " + e.getType()); 
            } catch (TTransportException e) { 
                e.printStackTrace(); 
            } catch (UserNotFound e) { 
                e.printStackTrace(); 
            } catch (TException e) { 
                e.printStackTrace(); 
            } 
            transport.close(); 
        } 
    }  
 
 
10.Thrift允许你选择 protocol ,transport和server。因为Thrift 最早是有C++开发的,Thrift在C++实现中有最大的变化。

Thrift支持 text 和 binary protocols,binary protocols要比text protocols,但是有时候 text protocols比较有用(例如:调试的时候)。支持的协议有:
TBinaryProtocol  -直接的二进制格式
TCompactProtocol  效率和高压缩编码数据
TDenseProtocoal  和TCompactProtocol相似,但是省略了meta信息,从哪里发送的,增加了receiver。还在实验中,java实现还不可用。
TJSONProtocoal 使用JSON
TSImpleJSONProtocoal  只写的protocol使用JSON。适合被脚本语言转化
TDebugProtocoal  使用人类可读的text 格式 帮助调试

上面的protocol 说明了 什么被传送,Thrift  transports 说明了怎样传送。支持的transport:
TSocket  使用 blocking socket I/O
TFramedTransport   以帧的形式发送,每帧前面是一个长度。要求服务器来non-blocking server
TFileTransport   写到文件。没有包括在java实现中。
TMemoryTransport   使用内存 I/O 。java实现中在内部使用了ByteArrayOutputStream
TZlibTransport 压缩 使用zlib。在java实现中还不可用

最后,thrift 提供了servers:
TSimpleServer  单线程 server,使用标准的blocking IO。用于测试
TThreadPoolServer  多线程  使用标准的blocking IO
TNonblockingServer  多线程  使用 non-blocking IO (java实现中使用了NIO channels)。TFramedTransport必须使用在这个服务器。

一个server只允许定义一个接口服务。这样的话多个接口需要多个server。这样会带来资源的浪费。同意通过继承接口的方式。
 各个server的性能对比见文章 http://liyonghui160com.iteye.com/admin/blogs/2088945
  • 大小: 1.8 KB
  • 大小: 17.8 KB
分享到:
评论

相关推荐

    Thrift初探:简单实现C#通讯服务程序

    本篇文章将探讨如何使用Thrift在C#环境中搭建一个简单的通信服务程序。 首先,我们需要了解Thrift的基本工作原理。Thrift通过定义一种中间描述文件(.thrift)来指定服务接口、数据结构和通信协议。这个文件被...

    thrift在windows下生成C#代码

    // 实现服务逻辑 } } public static void Main(string[] args) { var serverTransport = new TServerSocket(9090); var processor = new MyService.Processor(new MyServiceImpl()); var server = new ...

    thrift服务java调用C#完整代码.rar

    本项目提供了Java调用C#实现的Thrift服务的完整代码示例,有助于理解Thrift的工作原理以及如何在实际开发中应用。 首先,Thrift通过一个名为`.thrift`的接口定义文件来描述服务。这个文件包含了一系列的结构体...

    Thrift双向通讯java代码

    在服务器端,你需要实现服务接口中的所有方法。例如: ```java public class TestServiceImpl implements TestService.Iface { @Override public String sayHello(String name) { return "Hello, " + name; } }...

    Thrift Java 服务器 客户端通信

    3. 实现服务处理逻辑(服务处理器)。 4. 创建Thrift服务器并启动服务。 5. 创建Thrift客户端,连接到服务器并调用服务。 通过这种方式,Thrift简化了分布式系统之间的通信,并提供了高性能、可扩展的解决方案。...

    Thrift中实现Java与Python的RPC互相调用示例代码.rar

    在本示例中,我们将探讨如何使用Thrift在Java和Python之间实现RPC(Remote Procedure Call)的互相调用。 首先,我们需要了解Thrift IDL。在Thrift IDL文件中,我们可以定义服务接口、数据结构(如struct)和常量。...

    Java通过Thrift框架实现通讯的示例代码

    总之,Java通过Thrift实现通信是一个涉及服务定义、代码生成、服务处理程序实现、客户端调用等多个环节的过程。Thrift的优势在于其跨语言的特性,使得不同语言的系统间可以轻松进行数据交换,降低了分布式系统开发的...

    基于Thrift的Golang与c#程序互相访问

    本主题将详细探讨如何使用Thrift实现Golang与C#程序之间的互相访问。 首先,让我们了解Thrift的基本概念。Thrift是一种“远程过程调用”(RPC)框架,它提供了一种轻量级的编译器,可以将接口定义语言(IDL)转换为...

    Thrift-java学习小结

    本文将基于Thrift的Java实现,总结学习过程中的一些关键知识点,旨在帮助理解Thrift的工作原理以及如何在Java环境中应用。 一、Thrift简介 Thrift是一种远程过程调用(RPC)框架,它通过定义一种中间描述文件(....

    thrift实现http协议案例

    这个案例中的“MyThriftWebTest”可能是一个包含整个实现的测试工程,包括Thrift服务的定义、生成的Java代码以及Servlet的实现。通过运行这个测试工程,你可以了解如何将Thrift服务部署到支持HTTP的服务器上,如...

    java代码使用thrift2操作hbase示例

    通过这些示例,你可以更好地理解如何在实际项目中整合Java、Thrift2和HBase,以实现高效的数据存取。记住,实践是检验理论的最好方法,所以尝试运行这些示例,根据需求进行调整,你会发现自己的技能会得到显著提升。

    Thrift 示例代码_Java

    3. **实现服务**:在生成的 Java 类中填写服务逻辑,创建服务处理器和服务器实例。 4. **构建客户端**:使用生成的客户端代码创建服务代理,调用相应方法进行通信。 5. **运行和测试**:启动服务端,运行客户端进行...

    thrift开发入门java程序

    Thrift作为可伸缩的跨语言服务开发框架,网上的资源较少,这里是一个简单的入门小程序,文件中的mylib下包含了依赖的jar包,并且在file目录下放了一个简单的thrift文件和生成thrift-0.9.0.exe工具,直接使用 thrift-...

    thrift java build jar

    本文将详细介绍如何使用 Thrift 在 Java 环境下构建 `.jar` 文件,以便在不同的 Java 应用中使用 Thrift 生成的服务。 1. **安装 Thrift** 首先,你需要在本地安装 Thrift 编译器。访问 Thrift 官方网站...

    thrift 的 java 和 python结合例子

    总结起来,Thrift是实现跨语言服务调用的强大工具,通过其IDL和生成的代码,开发者可以轻松地在Java和Python等不同语言之间建立高效、可靠的通信。这个例子提供了学习和实践Thrift的一个基础起点,对于理解跨语言...

    thrift 生成的java包 全部的

    这个压缩包提供了一个完整的 Thrift Java 开发环境,包括了服务接口定义、实现和运行时所需的所有依赖,使得开发者可以快速搭建和测试基于 Thrift 的 Java 应用。在实际项目中,根据需求选择合适版本的库,并结合...

    Thrift下java服务器与客户端开发指南[归纳].pdf

    在生成的代码基础上,我们需要实现服务接口。创建一个`SomethingImpl.java`文件,该文件将实现`Something`服务的`ping`方法。例如: ```java public class SomethingImpl implements Something.Iface { @Override ...

    采用java操作thrift代码示例

    3. **实现服务**:在生成的`MyService.java`中,你需要实现`sayHello`方法。创建一个`MyServiceImpl.java`类并继承`MyService$Handler`: ```java public class MyServiceImpl extends MyService.Iface { @...

    c# thrift demo

    《C#实现Thrift应用详解》 Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年发布,旨在提供高效、灵活且可扩展的远程过程调用(RPC)解决方案。它允许开发者定义服务接口和服务数据类型,然后自动生成...

    thrift_java_demo和安装包

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年开发并开源,后来成为Apache基金会的顶级项目。它主要用于构建可扩展且高效率的分布式...在实际应用中,Thrift常用于构建微服务架构,实现服务间的高效通信。

Global site tag (gtag.js) - Google Analytics