Thrift总结(二)创建RPC服务

前面介绍了thrift 基础的东西,怎么写thrift 语法规范编写脚本,如何生成相关的语言的接口。不清楚的可以看这个《Thrift总结(一)介绍》。做好之前的准备工作以后,下面就开始如何用Thrift写RPC接口。

如何用Thrift写RPC接口

1. 打开之前下载的thrift 源码,thrift-0.10.0\lib\csharp\src ,编译生成Thrift.dll 文件。

 

2. 新建一个空白解决方案命名为HelloThrift。在解决方案根目录下创建一个lib文件夹,将刚刚生成的Thrift.dll文件放入lib文件夹中。在解决方案分中建立两个控制台程序和一个类库,控制台程序分别命名为HelloThrift.Client 和 HelloThrift.Server,类库命名为Thrift.Interface。Client、Server和Interface分别引用lib文件夹中的Thrift.dll文件,将准备工作中生成的HelloService文件导入到Interface类库中。Client和Server分别引用Interface。具体结果如下图所示

 

3. 创建完相关的项目和引用之后,在服务端HelloThrift.Server 创建一个类命名为MyHelloService,实现HelloService.Iface接口,代码如下:

  清单1.MyHelloService

using System;
using HelloThrift.Interface;

namespace HelloThrift.Server
{

    public class MyHelloService : HelloService.Iface
    {
        /// 

        /// 只有一个参数返回值为字符串类型的方法
        ///

 

        /// string类型参数
        /// 返回值为string类型
        public string HelloString(string para)
        {
            System.Threading.Thread.Sleep(1 * 1000);

            Console.WriteLine("客户端调用了HelloString方法");

            return para;
        }

        /// 

        /// 只有一个参数,返回值为int类型的方法
        ///

 

        /// 
        /// 返回值为int类型
        public int HelloInt(int para)
        {
            System.Threading.Thread.Sleep(1 * 1000);

            Console.WriteLine("客户端调用了HelloInt方法");

            return para;
        }

        /// 

        /// 只有一个bool类型参数,返回值为bool类型的方法
        ///

 

        /// 
        /// 返回值为bool类型
        public bool HelloBoolean(bool para)
        {
            System.Threading.Thread.Sleep(1 * 1000);

            Console.WriteLine("客户端调用了HelloBoolean方法");

            return para;
        }


        /// 

        /// 返回执行为空的方法
        ///

 

        public void HelloVoid()
        {
            System.Threading.Thread.Sleep(1 * 1000);

            Console.WriteLine("客户端调用了HelloVoid方法");

            Console.WriteLine("HelloWorld");
        }

        /// 

        /// 无参数,返回值为null的方法
        ///

 

        /// 返回值为null
        public string HelloNull()
        {
            System.Threading.Thread.Sleep(1 * 1000);

            Console.WriteLine("客户端调用了HelloNull方法");

            return null;

        }

    }
}

 

4. 创建服务器端HelloThrift.Server 宿主的实现代码,在Program.cs 中添加如下代码,这样一个thrift 服务器就创建好了。

  清单2.HelloThrift.Server

using System;
using Thrift;
using Thrift.Protocol;
using Thrift.Server;
using Thrift.Transport;
using HelloThrift.Interface;

namespace HelloThrift.Server
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //设置服务端口为8080
                TServerSocket serverTransport = new TServerSocket(9081);

                //设置传输协议工厂
                TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();

                //关联处理器与服务的实现
                TProcessor processor = new HelloService.Processor(new MyHelloService());

                //创建服务端对象
                TServer server = new TThreadPoolServer(processor, serverTransport, new TTransportFactory(), factory);

                Console.WriteLine("服务端正在监听9081端口");

                server.Serve();
            }
            catch (TTransportException ex)//捕获异常信息
            {
                //打印异常信息
                Console.WriteLine(ex.Message);

            }

        }
    }
}

 

5. 创建完服务端之后,下面开始生成一个客户端实现代码,在HelloThrift.Client  的 Program.cs 中添加如下代码:

  清单3.HelloThrift.Client

using System;
using HelloThrift.Interface;
using Thrift.Protocol;
using Thrift.Transport;

namespace HelloThrift.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {

                //设置服务端端口号和地址
                TTransport transport = new TSocket("localhost", 9081);
                transport.Open();

                //设置传输协议为二进制传输协议
                TProtocol protocol = new TBinaryProtocol(transport);

                //创建客户端对象
                HelloService.Client client = new HelloService.Client(protocol);

                //调用服务端的方法
                Console.WriteLine(client.HelloString("HelloThrift"));

                Console.ReadKey();

            }
            catch (TTransportException e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

上面的代码调用了服务端的HelloString方法,服务端也会返回传入的传输值,客户端将服务端返回的数据打印出来。好了完成了代码以后,将先启动Server,在启动Client。客户端调用结果 和 服务端请求显示。

 

说明

1. 关于使用Thrift 构建我们自己的rpc 的方法,这里基本讲完了。其他的方法本文就不再演示了,调用起来都是一样。

2. 后续会简单讨论一下Thrift 框架的通信原理。

3. 源代码下载,HelloThrift.rar

 

Thrift总结(一)介绍

这段时间,一直在整理公司的内部 rpc 服务接口,面临的一个问题就是:由于公司内部的系统由几个不同的语言编写的。C# ,java,node.js 等,如何实现这些内部系统之间的接口统一调用,确实是比较麻烦,本来考虑用webapi 但是感觉内部系统之间用webapi 效率不高。最终,我们还是考虑引入Thrift ,通过Thrift整合各个不同的RPC服务。下面就Thrift 如何使用,做个简单的介绍,本人也是初次接触。

  介绍

Thrift是一款由Fackbook开发的可伸缩、跨语言的服务开发框架,该框架已经开源并且加入的Apache项目。Thrift主要功能是:通过自定义的Interface Definition Language(IDL),可以创建基于RPC的客户端和服务端的服务代码。数据和服务代码的生成是通过Thrift内置的代码生成器来实现的。Thrift 的跨语言性体现在,它可以生成C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml , Delphi等语言的代码,且它们之间可以进行透明的通信。

Thrift 使得各个不同的语言的系统之间可以进行透明高效的通信。但是,Fackbook 的一贯作风就是只管发布,不管维护。所以,Thrift 目前还存在一些为解决的问题。大家在调研的时候,应该考虑清楚。

本文结合网络上的资源对从C#开发人员的角度简单介绍Thrift的使用,并且针对不同的传输协议和服务类型给出相应的C#实例,同时简单介绍Thrift异步客户端的实现。

 

Thrift代码生成器windows版下载地址

http://www.apache.org/dyn/closer.cgi?path=/thrift/0.10.0/thrift-0.10.0.exe

Thrift源码下载地址

http://www.apache.org/dyn/closer.cgi?path=/thrift/0.10.0/thrift-0.10.0.tar.gz

 

  Window 下安装配置

Thrift 不需要安装,只需下载windows版的 Thrift代码生成器即可,下载地址如上连接

注意:下载下来之后,必须把文件名字thrift-0.10.0.exe 改为  thrift.exe, 否则cmd会提示:thrift 不是内部命令的错误。

 

  创建thrift的语法规范编写脚本文件

根据thrift的语法规范编写脚本文件Hello.thrift,代码如下:

namespace csharp HelloThrift.Interface

service HelloService{

    string HelloString(1:string para)

    i32 HelloInt(1:i32 para)

    bool HelloBoolean(1:bool para)

    void HelloVoid()

    string HelloNull()

}

 

  生成Csharp 版的服务定义类

然后打开cmd切换到thrift代码生成工具的存放目录,在命令行中输入如下命令:thrift -gen csharp Hello.thrift

代码生成工具会自动在当前目录下把定义好的接口脚本生成C#代码,生成后的代码目录如下

接口脚本生成C#代码

/**
 * Autogenerated by Thrift Compiler (0.9.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Thrift;
using Thrift.Collections;
using System.Runtime.Serialization;
using Thrift.Protocol;
using Thrift.Transport;

namespace HelloThrift.Interface
{
  public partial class HelloService {
    public interface Iface {
      string HelloString(string para);
      #if SILVERLIGHT
      IAsyncResult Begin_HelloString(AsyncCallback callback, object state, string para);
      string End_HelloString(IAsyncResult asyncResult);
      #endif
      int HelloInt(int para);
      #if SILVERLIGHT
      IAsyncResult Begin_HelloInt(AsyncCallback callback, object state, int para);
      int End_HelloInt(IAsyncResult asyncResult);
      #endif
      bool HelloBoolean(bool para);
      #if SILVERLIGHT
      IAsyncResult Begin_HelloBoolean(AsyncCallback callback, object state, bool para);
      bool End_HelloBoolean(IAsyncResult asyncResult);
      #endif
      void HelloVoid();
      #if SILVERLIGHT
      IAsyncResult Begin_HelloVoid(AsyncCallback callback, object state);
      void End_HelloVoid(IAsyncResult asyncResult);
      #endif
      string HelloNull();
      #if SILVERLIGHT
      IAsyncResult Begin_HelloNull(AsyncCallback callback, object state);
      string End_HelloNull(IAsyncResult asyncResult);
      #endif
    }

    public class Client : IDisposable, Iface {
      public Client(TProtocol prot) : this(prot, prot)
      {
      }

      public Client(TProtocol iprot, TProtocol oprot)
      {
        iprot_ = iprot;
        oprot_ = oprot;
      }

      protected TProtocol iprot_;
      protected TProtocol oprot_;
      protected int seqid_;

      public TProtocol InputProtocol
      {
        get { return iprot_; }
      }
      public TProtocol OutputProtocol
      {
        get { return oprot_; }
      }


      #region " IDisposable Support "
      private bool _IsDisposed;

      // IDisposable
      public void Dispose()
      {
        Dispose(true);
      }
      

      protected virtual void Dispose(bool disposing)
      {
        if (!_IsDisposed)
        {
          if (disposing)
          {
            if (iprot_ != null)
            {
              ((IDisposable)iprot_).Dispose();
            }
            if (oprot_ != null)
            {
              ((IDisposable)oprot_).Dispose();
            }
          }
        }
        _IsDisposed = true;
      }
      #endregion


      
      #if SILVERLIGHT
      public IAsyncResult Begin_HelloString(AsyncCallback callback, object state, string para)
      {
        return send_HelloString(callback, state, para);
      }

      public string End_HelloString(IAsyncResult asyncResult)
      {
        oprot_.Transport.EndFlush(asyncResult);
        return recv_HelloString();
      }

      #endif

      public string HelloString(string para)
      {
        #if !SILVERLIGHT
        send_HelloString(para);
        return recv_HelloString();

        #else
        var asyncResult = Begin_HelloString(null, null, para);
        return End_HelloString(asyncResult);

        #endif
      }
      #if SILVERLIGHT
      public IAsyncResult send_HelloString(AsyncCallback callback, object state, string para)
      #else
      public void send_HelloString(string para)
      #endif
      {
        oprot_.WriteMessageBegin(new TMessage("HelloString", TMessageType.Call, seqid_));
        HelloString_args args = new HelloString_args();
        args.Para = para;
        args.Write(oprot_);
        oprot_.WriteMessageEnd();
        #if SILVERLIGHT
        return oprot_.Transport.BeginFlush(callback, state);
        #else
        oprot_.Transport.Flush();
        #endif
      }

      public string recv_HelloString()
      {
        TMessage msg = iprot_.ReadMessageBegin();
        if (msg.Type == TMessageType.Exception) {
          TApplicationException x = TApplicationException.Read(iprot_);
          iprot_.ReadMessageEnd();
          throw x;
        }
        HelloString_result result = new HelloString_result();
        result.Read(iprot_);
        iprot_.ReadMessageEnd();
        if (result.__isset.success) {
          return result.Success;
        }
        throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "HelloString failed: unknown result");
      }

      
      #if SILVERLIGHT
      public IAsyncResult Begin_HelloInt(AsyncCallback callback, object state, int para)
      {
        return send_HelloInt(callback, state, para);
      }

      public int End_HelloInt(IAsyncResult asyncResult)
      {
        oprot_.Transport.EndFlush(asyncResult);
        return recv_HelloInt();
      }

      #endif

      public int HelloInt(int para)
      {
        #if !SILVERLIGHT
        send_HelloInt(para);
        return recv_HelloInt();

        #else
        var asyncResult = Begin_HelloInt(null, null, para);
        return End_HelloInt(asyncResult);

        #endif
      }
      #if SILVERLIGHT
      public IAsyncResult send_HelloInt(AsyncCallback callback, object state, int para)
      #else
      public void send_HelloInt(int para)
      #endif
      {
        oprot_.WriteMessageBegin(new TMessage("HelloInt", TMessageType.Call, seqid_));
        HelloInt_args args = new HelloInt_args();
        args.Para = para;
        args.Write(oprot_);
        oprot_.WriteMessageEnd();
        #if SILVERLIGHT
        return oprot_.Transport.BeginFlush(callback, state);
        #else
        oprot_.Transport.Flush();
        #endif
      }

      public int recv_HelloInt()
      {
        TMessage msg = iprot_.ReadMessageBegin();
        if (msg.Type == TMessageType.Exception) {
          TApplicationException x = TApplicationException.Read(iprot_);
          iprot_.ReadMessageEnd();
          throw x;
        }
        HelloInt_result result = new HelloInt_result();
        result.Read(iprot_);
        iprot_.ReadMessageEnd();
        if (result.__isset.success) {
          return result.Success;
        }
        throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "HelloInt failed: unknown result");
      }

      
      #if SILVERLIGHT
      public IAsyncResult Begin_HelloBoolean(AsyncCallback callback, object state, bool para)
      {
        return send_HelloBoolean(callback, state, para);
      }

      public bool End_HelloBoolean(IAsyncResult asyncResult)
      {
        oprot_.Transport.EndFlush(asyncResult);
        return recv_HelloBoolean();
      }

      #endif

      public bool HelloBoolean(bool para)
      {
        #if !SILVERLIGHT
        send_HelloBoolean(para);
        return recv_HelloBoolean();

        #else
        var asyncResult = Begin_HelloBoolean(null, null, para);
        return End_HelloBoolean(asyncResult);

        #endif
      }
      #if SILVERLIGHT
      public IAsyncResult send_HelloBoolean(AsyncCallback callback, object state, bool para)
      #else
      public void send_HelloBoolean(bool para)
      #endif
      {
        oprot_.WriteMessageBegin(new TMessage("HelloBoolean", TMessageType.Call, seqid_));
        HelloBoolean_args args = new HelloBoolean_args();
        args.Para = para;
        args.Write(oprot_);
        oprot_.WriteMessageEnd();
        #if SILVERLIGHT
        return oprot_.Transport.BeginFlush(callback, state);
        #else
        oprot_.Transport.Flush();
        #endif
      }

      public bool recv_HelloBoolean()
      {
        TMessage msg = iprot_.ReadMessageBegin();
        if (msg.Type == TMessageType.Exception) {
          TApplicationException x = TApplicationException.Read(iprot_);
          iprot_.ReadMessageEnd();
          throw x;
        }
        HelloBoolean_result result = new HelloBoolean_result();
        result.Read(iprot_);
        iprot_.ReadMessageEnd();
        if (result.__isset.success) {
          return result.Success;
        }
        throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "HelloBoolean failed: unknown result");
      }

      
      #if SILVERLIGHT
      public IAsyncResult Begin_HelloVoid(AsyncCallback callback, object state)
      {
        return send_HelloVoid(callback, state);
      }

      public void End_HelloVoid(IAsyncResult asyncResult)
      {
        oprot_.Transport.EndFlush(asyncResult);
        recv_HelloVoid();
      }

      #endif

      public void HelloVoid()
      {
        #if !SILVERLIGHT
        send_HelloVoid();
        recv_HelloVoid();

        #else
        var asyncResult = Begin_HelloVoid(null, null);
        End_HelloVoid(asyncResult);

        #endif
      }
      #if SILVERLIGHT
      public IAsyncResult send_HelloVoid(AsyncCallback callback, object state)
      #else
      public void send_HelloVoid()
      #endif
      {
        oprot_.WriteMessageBegin(new TMessage("HelloVoid", TMessageType.Call, seqid_));
        HelloVoid_args args = new HelloVoid_args();
        args.Write(oprot_);
        oprot_.WriteMessageEnd();
        #if SILVERLIGHT
        return oprot_.Transport.BeginFlush(callback, state);
        #else
        oprot_.Transport.Flush();
        #endif
      }

      public void recv_HelloVoid()
      {
        TMessage msg = iprot_.ReadMessageBegin();
        if (msg.Type == TMessageType.Exception) {
          TApplicationException x = TApplicationException.Read(iprot_);
          iprot_.ReadMessageEnd();
          throw x;
        }
        HelloVoid_result result = new HelloVoid_result();
        result.Read(iprot_);
        iprot_.ReadMessageEnd();
        return;
      }

      
      #if SILVERLIGHT
      public IAsyncResult Begin_HelloNull(AsyncCallback callback, object state)
      {
        return send_HelloNull(callback, state);
      }

      public string End_HelloNull(IAsyncResult asyncResult)
      {
        oprot_.Transport.EndFlush(asyncResult);
        return recv_HelloNull();
      }

      #endif

      public string HelloNull()
      {
        #if !SILVERLIGHT
        send_HelloNull();
        return recv_HelloNull();

        #else
        var asyncResult = Begin_HelloNull(null, null);
        return End_HelloNull(asyncResult);

        #endif
      }
      #if SILVERLIGHT
      public IAsyncResult send_HelloNull(AsyncCallback callback, object state)
      #else
      public void send_HelloNull()
      #endif
      {
        oprot_.WriteMessageBegin(new TMessage("HelloNull", TMessageType.Call, seqid_));
        HelloNull_args args = new HelloNull_args();
        args.Write(oprot_);
        oprot_.WriteMessageEnd();
        #if SILVERLIGHT
        return oprot_.Transport.BeginFlush(callback, state);
        #else
        oprot_.Transport.Flush();
        #endif
      }

      public string recv_HelloNull()
      {
        TMessage msg = iprot_.ReadMessageBegin();
        if (msg.Type == TMessageType.Exception) {
          TApplicationException x = TApplicationException.Read(iprot_);
          iprot_.ReadMessageEnd();
          throw x;
        }
        HelloNull_result result = new HelloNull_result();
        result.Read(iprot_);
        iprot_.ReadMessageEnd();
        if (result.__isset.success) {
          return result.Success;
        }
        throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "HelloNull failed: unknown result");
      }

    }
    public class Processor : TProcessor {
      public Processor(Iface iface)
      {
        iface_ = iface;
        processMap_["HelloString"] = HelloString_Process;
        processMap_["HelloInt"] = HelloInt_Process;
        processMap_["HelloBoolean"] = HelloBoolean_Process;
        processMap_["HelloVoid"] = HelloVoid_Process;
        processMap_["HelloNull"] = HelloNull_Process;
      }

      protected delegate void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);
      private Iface iface_;
      protected Dictionary<string, ProcessFunction> processMap_ = new Dictionary<string, ProcessFunction>();

      public bool Process(TProtocol iprot, TProtocol oprot)
      {
        try
        {
          TMessage msg = iprot.ReadMessageBegin();
          ProcessFunction fn;
          processMap_.TryGetValue(msg.Name, out fn);
          if (fn == null) {
            TProtocolUtil.Skip(iprot, TType.Struct);
            iprot.ReadMessageEnd();
            TApplicationException x = new TApplicationException (TApplicationException.ExceptionType.UnknownMethod, "Invalid method name: '" + msg.Name + "'");
            oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID));
            x.Write(oprot);
            oprot.WriteMessageEnd();
            oprot.Transport.Flush();
            return true;
          }
          fn(msg.SeqID, iprot, oprot);
        }
        catch (IOException)
        {
          return false;
        }
        return true;
      }

      public void HelloString_Process(int seqid, TProtocol iprot, TProtocol oprot)
      {
        HelloString_args args = new HelloString_args();
        args.Read(iprot);
        iprot.ReadMessageEnd();
        HelloString_result result = new HelloString_result();
        result.Success = iface_.HelloString(args.Para);
        oprot.WriteMessageBegin(new TMessage("HelloString", TMessageType.Reply, seqid)); 
        result.Write(oprot);
        oprot.WriteMessageEnd();
        oprot.Transport.Flush();
      }

      public void HelloInt_Process(int seqid, TProtocol iprot, TProtocol oprot)
      {
        HelloInt_args args = new HelloInt_args();
        args.Read(iprot);
        iprot.ReadMessageEnd();
        HelloInt_result result = new HelloInt_result();
        result.Success = iface_.HelloInt(args.Para);
        oprot.WriteMessageBegin(new TMessage("HelloInt", TMessageType.Reply, seqid)); 
        result.Write(oprot);
        oprot.WriteMessageEnd();
        oprot.Transport.Flush();
      }

      public void HelloBoolean_Process(int seqid, TProtocol iprot, TProtocol oprot)
      {
        HelloBoolean_args args = new HelloBoolean_args();
        args.Read(iprot);
        iprot.ReadMessageEnd();
        HelloBoolean_result result = new HelloBoolean_result();
        result.Success = iface_.HelloBoolean(args.Para);
        oprot.WriteMessageBegin(new TMessage("HelloBoolean", TMessageType.Reply, seqid)); 
        result.Write(oprot);
        oprot.WriteMessageEnd();
        oprot.Transport.Flush();
      }

      public void HelloVoid_Process(int seqid, TProtocol iprot, TProtocol oprot)
      {
        HelloVoid_args args = new HelloVoid_args();
        args.Read(iprot);
        iprot.ReadMessageEnd();
        HelloVoid_result result = new HelloVoid_result();
        iface_.HelloVoid();
        oprot.WriteMessageBegin(new TMessage("HelloVoid", TMessageType.Reply, seqid)); 
        result.Write(oprot);
        oprot.WriteMessageEnd();
        oprot.Transport.Flush();
      }

      public void HelloNull_Process(int seqid, TProtocol iprot, TProtocol oprot)
      {
        HelloNull_args args = new HelloNull_args();
        args.Read(iprot);
        iprot.ReadMessageEnd();
        HelloNull_result result = new HelloNull_result();
        result.Success = iface_.HelloNull();
        oprot.WriteMessageBegin(new TMessage("HelloNull", TMessageType.Reply, seqid)); 
        result.Write(oprot);
        oprot.WriteMessageEnd();
        oprot.Transport.Flush();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloString_args : TBase
    {
      private string _para;

      public string Para
      {
        get
        {
          return _para;
        }
        set
        {
          __isset.para = true;
          this._para = value;
        }
      }


      public Isset __isset;
      #if !SILVERLIGHT
      [Serializable]
      #endif
      public struct Isset {
        public bool para;
      }

      public HelloString_args() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              case 1:
                if (field.Type == TType.String) {
                  Para = iprot.ReadString();
                } else { 
                  TProtocolUtil.Skip(iprot, field.Type);
                }
                break;
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloString_args");
          oprot.WriteStructBegin(struc);
          TField field = new TField();
          if (Para != null && __isset.para) {
            field.Name = "para";
            field.Type = TType.String;
            field.ID = 1;
            oprot.WriteFieldBegin(field);
            oprot.WriteString(Para);
            oprot.WriteFieldEnd();
          }
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloString_args(");
        bool __first = true;
        if (Para != null && __isset.para) {
          if(!__first) { __sb.Append(", "); }
          __first = false;
          __sb.Append("Para: ");
          __sb.Append(Para);
        }
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloString_result : TBase
    {
      private string _success;

      public string Success
      {
        get
        {
          return _success;
        }
        set
        {
          __isset.success = true;
          this._success = value;
        }
      }


      public Isset __isset;
      #if !SILVERLIGHT
      [Serializable]
      #endif
      public struct Isset {
        public bool success;
      }

      public HelloString_result() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              case 0:
                if (field.Type == TType.String) {
                  Success = iprot.ReadString();
                } else { 
                  TProtocolUtil.Skip(iprot, field.Type);
                }
                break;
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloString_result");
          oprot.WriteStructBegin(struc);
          TField field = new TField();

          if (this.__isset.success) {
            if (Success != null) {
              field.Name = "Success";
              field.Type = TType.String;
              field.ID = 0;
              oprot.WriteFieldBegin(field);
              oprot.WriteString(Success);
              oprot.WriteFieldEnd();
            }
          }
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloString_result(");
        bool __first = true;
        if (Success != null && __isset.success) {
          if(!__first) { __sb.Append(", "); }
          __first = false;
          __sb.Append("Success: ");
          __sb.Append(Success);
        }
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloInt_args : TBase
    {
      private int _para;

      public int Para
      {
        get
        {
          return _para;
        }
        set
        {
          __isset.para = true;
          this._para = value;
        }
      }


      public Isset __isset;
      #if !SILVERLIGHT
      [Serializable]
      #endif
      public struct Isset {
        public bool para;
      }

      public HelloInt_args() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              case 1:
                if (field.Type == TType.I32) {
                  Para = iprot.ReadI32();
                } else { 
                  TProtocolUtil.Skip(iprot, field.Type);
                }
                break;
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloInt_args");
          oprot.WriteStructBegin(struc);
          TField field = new TField();
          if (__isset.para) {
            field.Name = "para";
            field.Type = TType.I32;
            field.ID = 1;
            oprot.WriteFieldBegin(field);
            oprot.WriteI32(Para);
            oprot.WriteFieldEnd();
          }
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloInt_args(");
        bool __first = true;
        if (__isset.para) {
          if(!__first) { __sb.Append(", "); }
          __first = false;
          __sb.Append("Para: ");
          __sb.Append(Para);
        }
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloInt_result : TBase
    {
      private int _success;

      public int Success
      {
        get
        {
          return _success;
        }
        set
        {
          __isset.success = true;
          this._success = value;
        }
      }


      public Isset __isset;
      #if !SILVERLIGHT
      [Serializable]
      #endif
      public struct Isset {
        public bool success;
      }

      public HelloInt_result() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              case 0:
                if (field.Type == TType.I32) {
                  Success = iprot.ReadI32();
                } else { 
                  TProtocolUtil.Skip(iprot, field.Type);
                }
                break;
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloInt_result");
          oprot.WriteStructBegin(struc);
          TField field = new TField();

          if (this.__isset.success) {
            field.Name = "Success";
            field.Type = TType.I32;
            field.ID = 0;
            oprot.WriteFieldBegin(field);
            oprot.WriteI32(Success);
            oprot.WriteFieldEnd();
          }
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloInt_result(");
        bool __first = true;
        if (__isset.success) {
          if(!__first) { __sb.Append(", "); }
          __first = false;
          __sb.Append("Success: ");
          __sb.Append(Success);
        }
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloBoolean_args : TBase
    {
      private bool _para;

      public bool Para
      {
        get
        {
          return _para;
        }
        set
        {
          __isset.para = true;
          this._para = value;
        }
      }


      public Isset __isset;
      #if !SILVERLIGHT
      [Serializable]
      #endif
      public struct Isset {
        public bool para;
      }

      public HelloBoolean_args() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              case 1:
                if (field.Type == TType.Bool) {
                  Para = iprot.ReadBool();
                } else { 
                  TProtocolUtil.Skip(iprot, field.Type);
                }
                break;
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloBoolean_args");
          oprot.WriteStructBegin(struc);
          TField field = new TField();
          if (__isset.para) {
            field.Name = "para";
            field.Type = TType.Bool;
            field.ID = 1;
            oprot.WriteFieldBegin(field);
            oprot.WriteBool(Para);
            oprot.WriteFieldEnd();
          }
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloBoolean_args(");
        bool __first = true;
        if (__isset.para) {
          if(!__first) { __sb.Append(", "); }
          __first = false;
          __sb.Append("Para: ");
          __sb.Append(Para);
        }
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloBoolean_result : TBase
    {
      private bool _success;

      public bool Success
      {
        get
        {
          return _success;
        }
        set
        {
          __isset.success = true;
          this._success = value;
        }
      }


      public Isset __isset;
      #if !SILVERLIGHT
      [Serializable]
      #endif
      public struct Isset {
        public bool success;
      }

      public HelloBoolean_result() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              case 0:
                if (field.Type == TType.Bool) {
                  Success = iprot.ReadBool();
                } else { 
                  TProtocolUtil.Skip(iprot, field.Type);
                }
                break;
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloBoolean_result");
          oprot.WriteStructBegin(struc);
          TField field = new TField();

          if (this.__isset.success) {
            field.Name = "Success";
            field.Type = TType.Bool;
            field.ID = 0;
            oprot.WriteFieldBegin(field);
            oprot.WriteBool(Success);
            oprot.WriteFieldEnd();
          }
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloBoolean_result(");
        bool __first = true;
        if (__isset.success) {
          if(!__first) { __sb.Append(", "); }
          __first = false;
          __sb.Append("Success: ");
          __sb.Append(Success);
        }
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloVoid_args : TBase
    {

      public HelloVoid_args() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloVoid_args");
          oprot.WriteStructBegin(struc);
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloVoid_args(");
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloVoid_result : TBase
    {

      public HelloVoid_result() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloVoid_result");
          oprot.WriteStructBegin(struc);

          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloVoid_result(");
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloNull_args : TBase
    {

      public HelloNull_args() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloNull_args");
          oprot.WriteStructBegin(struc);
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloNull_args(");
        __sb.Append(")");
        return __sb.ToString();
      }

    }


    #if !SILVERLIGHT
    [Serializable]
    #endif
    public partial class HelloNull_result : TBase
    {
      private string _success;

      public string Success
      {
        get
        {
          return _success;
        }
        set
        {
          __isset.success = true;
          this._success = value;
        }
      }


      public Isset __isset;
      #if !SILVERLIGHT
      [Serializable]
      #endif
      public struct Isset {
        public bool success;
      }

      public HelloNull_result() {
      }

      public void Read (TProtocol iprot)
      {
        iprot.IncrementRecursionDepth();
        try
        {
          TField field;
          iprot.ReadStructBegin();
          while (true)
          {
            field = iprot.ReadFieldBegin();
            if (field.Type == TType.Stop) { 
              break;
            }
            switch (field.ID)
            {
              case 0:
                if (field.Type == TType.String) {
                  Success = iprot.ReadString();
                } else { 
                  TProtocolUtil.Skip(iprot, field.Type);
                }
                break;
              default: 
                TProtocolUtil.Skip(iprot, field.Type);
                break;
            }
            iprot.ReadFieldEnd();
          }
          iprot.ReadStructEnd();
        }
        finally
        {
          iprot.DecrementRecursionDepth();
        }
      }

      public void Write(TProtocol oprot) {
        oprot.IncrementRecursionDepth();
        try
        {
          TStruct struc = new TStruct("HelloNull_result");
          oprot.WriteStructBegin(struc);
          TField field = new TField();

          if (this.__isset.success) {
            if (Success != null) {
              field.Name = "Success";
              field.Type = TType.String;
              field.ID = 0;
              oprot.WriteFieldBegin(field);
              oprot.WriteString(Success);
              oprot.WriteFieldEnd();
            }
          }
          oprot.WriteFieldStop();
          oprot.WriteStructEnd();
        }
        finally
        {
          oprot.DecrementRecursionDepth();
        }
      }

      public override string ToString() {
        StringBuilder __sb = new StringBuilder("HelloNull_result(");
        bool __first = true;
        if (Success != null && __isset.success) {
          if(!__first) { __sb.Append(", "); }
          __first = false;
          __sb.Append("Success: ");
          __sb.Append(Success);
        }
        __sb.Append(")");
        return __sb.ToString();
      }

    }

  }
}

HelloService定义了服务HelloService的五个方法,每个方法包含一个方法名,参数列表和返回类型。每个参数包括参数序号,参数类型以及参数名。包含了在 Hello.thrift 文件中描述的服务 HelloService 的接口定义,即HelloService.Iface 接口,以及服务调用的底层通信细节,包括客户端的调用逻辑HelloService.Client 以及服务器端的处理逻辑HelloService.Processor,用于构建客户端和服务器端的功能。

这样,C#版的接口代码就生成成功了。非常简单,下一篇,会具体的介绍服务器端如何实现调用这些接口和客户端如何调用这些接口。