zoukankan      html  css  js  c++  java
  • Thrift初探:简单实现C#通讯服务程序

          好久没有写文章了,由于换工作了,所以一直没有时间来写博。今天抽个空练练手下~最近接触了下Thrift,网上也有很多文章对于Thrift做了说明:
          Thrift是一种可伸缩的跨语言服务框架,它结合了功能强大的软件堆栈的代码生成引擎,以建设服务,工作效率和无缝地与C++,C#,Java,Python和PHP和Ruby结合。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
          它的好处是什么?当然是它支持大多数时下流行的语言。通过Thrift命令自动生成相应的语言脚本。而进行一些性能对比中,它的好处显而易见。

    image

    以上是传输相同的内容时内容大小的对比。

    image

    以上是运行开销比较结果。

    TCompactProtocol和TBinaryProtocol是Thrift支持的两种协议,其中TCompactProtocol使用Variable-Length Quantity (VLQ) 编码对数据进行压缩。

    详细可以查看:http://www.javabloger.com/article/apache-thrift-architecture.html

    接下来,我想讲述一下如何使用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. 这里我利用文章(http://www.javabloger.com/article/thrift-java-code-example.html)的例子(该例子生成Java源码的),完成一个C#版本的示例。

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

    namespace java com.javabloger.gen.code   #  注释1

    struct Blog {   #  注释2 
        
    1string topic 
        
    2: binary content 
        
    3: i64    createdTime 
        
    4string id 
        
    5string 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)  
    }

    4. 执行thrift命令:thrift -gen csharp testCsharp.thrift,这里说明一下:参数"csharp”意味着这里将自动生成C#代码,如果这里写java,python等等,可以用"java"或者"py”代替。

    于是得到gen-csharp的目录,这个目录里面就包含支持Thrift的Blog以及ThriftCase的源代码,具体里面都生成什么代码,后面会做出介绍。

    image

    5. 然后,我现在打开SVN源码中的 trunk\lib\csharp\ 路径,我用项目打开

    image

    编译后,得到Thrift.dll文件,为了后面使用Thrift做准备。

    6.新建工程,添加Server以及Client项目,把刚才生成的代码文件放入Common项目中。让Client和Server项目引用Thrift.dll类库。

    image

    7. 编写服务端程序:

    public class Server 

        
    public void Start() 
        { 
            TServerSocket serverTransport 
    = new TServerSocket(79110false); 
            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"); 
            } 
        }

    让它继承ThriftCase.Iface接口。

    8. 编写客户端程序:

     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(
    1021"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(); 
            } 
        }

    9. 运行Server以及Client:

    image

    从客户端调用的方法,服务端已经接收到了数据。

    源代码下载:ThriftCSharp.rar

    后面的文章,我会具体介绍下Thrift的工作机制和原理。

  • 相关阅读:
    线性支持向量机分类
    字符识别--模型集成
    字符识别--模型的训练与验证
    反射案例当中pro.load()报错问题的解决
    字节码对象功能
    BS案例服务器之系统找不到指定路径
    内部类接口实现线程
    多个异常,一次捕获,多次处理
    Objects.requireNonNull
    intellij idea编译java出现kotlin:connecting to daemon
  • 原文地址:https://www.cnblogs.com/liping13599168/p/2176836.html
Copyright © 2011-2022 走看看