`

基于Thrift协议的C#客户端

 
阅读更多

一.如果你对Thrift不够了解,请先看这篇入门文章

http://www.cnblogs.com/hanmos/archive/2011/09/15/2177891.html

二.以下是说明如何基于Thrift协议,开发一个C#的客户端,用以发布C#的跨语言服务(封装原生的thrift0.9)

1.服务的发布类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thrift;
using Thrift.Protocol;
using System.IO;
using System.Reflection;
using System.Dynamic;
using saf.cshap.client;
using Thrift.Collections;

namespace com.jd.saf
{
    public class SafProcesser : TProcessor
    {
        public  dynamic service;

        public bool Process(TProtocol iprot, TProtocol oprot)
        {
            try
            {
                TMessage msg = iprot.ReadMessageBegin();
                ///反射,真正方法的调用
                dynamic[] args = readPara(iprot);
                dynamic result = service.GetType().InvokeMember(msg.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, Type.DefaultBinder, service, args);
                iprot.ReadMessageEnd();
                ///方法的执行结果返回给client
                oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Reply, msg.SeqID));
                Write(oprot, result, msg.Name);
                oprot.WriteMessageEnd();
                oprot.Transport.Flush();
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 读取iport中的方法参数
        /// </summary>
        /// <returns></returns>
        private dynamic[] readPara(TProtocol iprot)
        {
            iprot.ReadStructBegin();
            List<dynamic> paraList = new List<dynamic>();
            bool flag = true;
            while (flag)
            {
                try
                {
                    paraList.Add(readField(iprot, TType.Stop));
                }
                catch
                {
                    flag = false;
                }
              
            }
            iprot.ReadStructEnd();
            return paraList.ToArray();
        }

        private dynamic readField(TProtocol iprot, TType type)
        {
            type = (type == TType.Stop ? iprot.ReadFieldBegin().Type : type);
            dynamic para = null;
            switch (type)
            {
                case TType.Stop: throw new Exception();

                case TType.String: para = iprot.ReadString(); break;

                case TType.Bool: para = iprot.ReadBool(); break;

                case TType.Byte: para = iprot.ReadByte(); break;

                case TType.Double: para = iprot.ReadDouble(); break;

                case TType.I16: para = iprot.ReadI16(); break;

                case TType.I32: para = iprot.ReadI32(); break;

                case TType.I64: para = iprot.ReadI64(); break;

                case TType.List:
                    TList list = iprot.ReadListBegin();
                    //List<dynamic> pList = new List<dynamic>();
                    //for (int i = 0; i < list.Count; i++)
                    //{
                    //    pList.Add(readField(iprot, list.ElementType));
                    //}
                    //para = pList;
                    para = readTList(list, iprot);
                    iprot.ReadListEnd();
                    break;
                case TType.Set:
                    TSet set = iprot.ReadSetBegin();
                    //THashSet<object> pSet = new THashSet<object>();
                    //for (int i = 0; i < set.Count; i++)
                    //{
                    //    pSet.Add(readField(iprot, set.ElementType));
                    //}
                    para = readTSet(set, iprot);
                    iprot.ReadSetEnd();
                    break;
                case TType.Map:
                    TMap map = iprot.ReadMapBegin();
                    Dictionary<dynamic, dynamic> pmap = new Dictionary<dynamic, dynamic>();
                    for (int i = 0; i < map.Count; i++)
                    {
                        var key = readField(iprot, map.KeyType);
                        var value = readField(iprot, map.ValueType);
                        pmap[key] = value;
                    }
                    para = pmap;
                    iprot.ReadMapEnd();
                    break;
                //case TType.Struct :
                    //TStruct st = iprot.ReadStructBegin();
                    //反射生成实例,反射调用方法
                    //para = st.GetType();
                   // iprot.ReadStructEnd();
                   // break;
                default:
                    TProtocolUtil.Skip(iprot, type); break;
            }
            iprot.ReadFieldEnd();
            return para;
        }

        private dynamic readTList(TList list, TProtocol iprot)
        {
            TType type = list.ElementType;
            dynamic para = null;
            switch (type)
            {
                case TType.String:
                    para = new List<string>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(iprot, list.ElementType));
                    }
                    break;
                case TType.I32:
                    para = new List<int>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(iprot, list.ElementType));
                    }
                    break;
                case TType.I16:
                    para = new List<short>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(iprot, list.ElementType));
                    }
                    break;
                case TType.I64:
                    para = new List<long>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(iprot, list.ElementType));
                    }
                    break;
                case TType.Bool:
                    para = new List<bool>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(iprot, list.ElementType));
                    }
                    break;
                case TType.Byte:
                    para = new List<byte>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(iprot, list.ElementType));
                    }
                    break;
                case TType.Double:
                    para = new List<double>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(iprot, list.ElementType));
                    }
                    break;
            }
            return para;
        }

        private dynamic readTSet(TSet set, TProtocol iprot)
        {
            TType type = set.ElementType;
            dynamic para = null;
            switch (type)
            {
                case TType.String:
                    para = new THashSet<string>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(iprot, set.ElementType));
                    }
                    break;
                case TType.I32:
                    para = new THashSet<int>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(iprot, set.ElementType));
                    }
                    break;
                case TType.I16:
                    para = new THashSet<short>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(iprot, set.ElementType));
                    }
                    break;
                case TType.I64:
                    para = new THashSet<long>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(iprot, set.ElementType));
                    }
                    break;
                case TType.Bool:
                    para = new THashSet<bool>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(iprot, set.ElementType));
                    }
                    break;
                case TType.Byte:
                    para = new THashSet<byte>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(iprot, set.ElementType));
                    }
                    break;
                case TType.Double:
                    para = new THashSet<double>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(iprot, set.ElementType));
                    }
                    break;
            }
            return para;
        }

        /// <summary>
        /// 发消息给客户端
        /// </summary>
        /// <param name="oprot"></param>
        /// <param name="result"></param>
        /// <param name="msgName"></param>
        private void Write(TProtocol oprot, dynamic result, string msgName)
        {
            TStruct struc = new TStruct(msgName + "_result");
            oprot.WriteStructBegin(struc);
            if (result != null)
            {
                TField field = new TField();
                field.Name = "Success";
                field.ID = 0;
                write(field, result, oprot);
            }
            oprot.WriteFieldStop();
            oprot.WriteStructEnd();
        }

        private void write(TField field, object result, TProtocol oprot)
        {
            if (result is System.String)
            {
                field.Type = TType.String;
                oprot.WriteFieldBegin(field);
                oprot.WriteString((string)result);
                oprot.WriteFieldEnd();
            }
            else if (result is System.Boolean)
            {
                field.Type = TType.Bool;
                oprot.WriteFieldBegin(field);
                oprot.WriteBool((bool)result);
                oprot.WriteFieldEnd();
            }
            else if (result is System.Int32)
            {
                field.Type = TType.I32;
                oprot.WriteFieldBegin(field);
                oprot.WriteI32((int)result);
                oprot.WriteFieldEnd();
            }
            else if (result is System.Int16)
            {
                field.Type = TType.I16;
                oprot.WriteFieldBegin(field);
                oprot.WriteI16((short)result);
                oprot.WriteFieldEnd();
            }
            else if (result is System.Int64)
            {
                field.Type = TType.I64;
                oprot.WriteFieldBegin(field);
                oprot.WriteI64((long)result);
                oprot.WriteFieldEnd();
            }
            else if (result is System.Byte)
            {
                field.Type = TType.Byte;
                oprot.WriteFieldBegin(field);
                oprot.WriteByte((byte)result);
                oprot.WriteFieldEnd();
            }
            else if (result is System.Double)
            {
                field.Type = TType.Double;
                oprot.WriteFieldBegin(field);
                oprot.WriteDouble((double)result);
                oprot.WriteFieldEnd();
            }
            else if(result.GetType().Name.Contains("List"))
            {
                field.Type = TType.List;
                oprot.WriteFieldBegin(field);
                writeList(field, result, oprot);
                oprot.WriteFieldEnd();
            }
            else if (result.GetType().Name.Contains("Set"))
            {
                field.Type = TType.Set;
                oprot.WriteFieldBegin(field);
                writeSet(field, result, oprot);
                oprot.WriteFieldEnd();

            }
            else if (result.GetType().Name.Contains("Dictionary"))
            {
                field.Type = TType.Map;
                oprot.WriteFieldBegin(field);
                writeMap(field, result, oprot);
                oprot.WriteFieldEnd();
            }
        }

        private void writeList(TField field, object result, TProtocol oprot)
        {
            if (result is System.Collections.Generic.List<string>)
            {
                List<string> list = (List<string>)result;
                oprot.WriteListBegin(new TList(TType.String, list.Count));
                foreach (string el in list)
                {
                    oprot.WriteString(el);
                }
                oprot.WriteListEnd();
            }
            else if (result is System.Collections.Generic.List<int>)
            {
                List<int> list = (List<int>)result;
                oprot.WriteListBegin(new TList(TType.I32, list.Count));
                foreach (int el in list)
                {
                    oprot.WriteI32(el);
                }
                oprot.WriteListEnd();
            }
            else if (result is System.Collections.Generic.List<long>)
            {
                List<long> list = (List<long>)result;
                oprot.WriteListBegin(new TList(TType.I64, list.Count));
                foreach (long el in list)
                {
                    oprot.WriteI64(el);
                }
                oprot.WriteListEnd();
            }
            else if (result is System.Collections.Generic.List<short>)
            {
                List<short> list = (List<short>)result;
                oprot.WriteListBegin(new TList(TType.I16, list.Count));
                foreach (short el in list)
                {
                    oprot.WriteI16(el);
                }
                oprot.WriteListEnd();
            }
            else if (result is System.Collections.Generic.List<bool>)
            {
                List<bool> list = (List<bool>)result;
                oprot.WriteListBegin(new TList(TType.Bool, list.Count));
                foreach (bool el in list)
                {
                    oprot.WriteBool(el);
                }
                oprot.WriteListEnd();
            }
            else if (result is System.Collections.Generic.List<byte>)
            {
                List<byte> list = (List<byte>)result;
                oprot.WriteListBegin(new TList(TType.Byte, list.Count));
                foreach (byte el in list)
                {
                    oprot.WriteByte(el);
                }
                oprot.WriteListEnd();
            }
            else if (result is System.Collections.Generic.List<double>)
            {
                List<double> list = (List<double>)result;
                oprot.WriteListBegin(new TList(TType.Double, list.Count));
                foreach (double el in list)
                {
                    oprot.WriteDouble(el);
                }
                oprot.WriteListEnd();
            }
        }

        private void writeSet(TField field, object result, TProtocol oprot)
        {
            if (result is THashSet<string>)
            {
                THashSet<string> set = (THashSet<string>)result;
                oprot.WriteSetBegin(new TSet(TType.String, set.Count));
                foreach (string el in set)
                {
                    oprot.WriteString(el);
                }
                oprot.WriteSetEnd();
            }
            else if (result is THashSet<int>)
            {
                THashSet<int> set = (THashSet<int>)result;
                oprot.WriteSetBegin(new TSet(TType.I32, set.Count));
                foreach (int el in set)
                {
                    oprot.WriteI32(el);
                }
                oprot.WriteSetEnd();
            }
            else if (result is THashSet<long>)
            {
                THashSet<long> set = (THashSet<long>)result;
                oprot.WriteSetBegin(new TSet(TType.I64, set.Count));
                foreach (long el in set)
                {
                    oprot.WriteI64(el);
                }
                oprot.WriteSetEnd();
            }
            else if (result is THashSet<short>)
            {
                THashSet<short> set = (THashSet<short>)result;
                oprot.WriteSetBegin(new TSet(TType.I16, set.Count));
                foreach (short el in set)
                {
                    oprot.WriteI16(el);
                }
                oprot.WriteSetEnd();
            }
            else if (result is THashSet<bool>)
            {
                THashSet<bool> set = (THashSet<bool>)result;
                oprot.WriteSetBegin(new TSet(TType.Bool, set.Count));
                foreach (bool el in set)
                {
                    oprot.WriteBool(el);
                }
                oprot.WriteSetEnd();
            }
            else if (result is THashSet<byte>)
            {
                THashSet<byte> set = (THashSet<byte>)result;
                oprot.WriteSetBegin(new TSet(TType.Byte, set.Count));
                foreach (byte el in set)
                {
                    oprot.WriteByte(el);
                }
                oprot.WriteSetEnd();
            }
            else if (result is THashSet<double>)
            {
                THashSet<double> set = (THashSet<double>)result;
                oprot.WriteSetBegin(new TSet(TType.Double, set.Count));
                foreach (double el in set)
                {
                    oprot.WriteDouble(el);
                }
                oprot.WriteSetEnd();
            }

        }

        private void writeMap(TField field, object result, TProtocol oprot)
        {
            if (result is Dictionary<string, string>)
            {
                Dictionary<string, string> map = (Dictionary<string, string>)result;
                oprot.WriteMapBegin(new TMap(TType.String, TType.String, map.Count));
                foreach (string key in map.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteString(map[key]);
                }
                oprot.WriteMapEnd();
            }
            if (result is Dictionary<string, int>)
            {
                Dictionary<string, int> map = (Dictionary<string, int>)result;
                oprot.WriteMapBegin(new TMap(TType.String, TType.I32, map.Count));
                foreach (string key in map.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteI32(map[key]);
                }
                oprot.WriteMapEnd();
            }
            if (result is Dictionary<string, long>)
            {
                Dictionary<string, long> map = (Dictionary<string, long>)result;
                oprot.WriteMapBegin(new TMap(TType.String, TType.I64, map.Count));
                foreach (string key in map.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteI64(map[key]);
                }
                oprot.WriteMapEnd();
            }
            if (result is Dictionary<string, short>)
            {
                Dictionary<string, short> map = (Dictionary<string, short>)result;
                oprot.WriteMapBegin(new TMap(TType.String, TType.I16, map.Count));
                foreach (string key in map.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteI16(map[key]);
                }
                oprot.WriteMapEnd();
            }
            if (result is Dictionary<string, byte>)
            {
                Dictionary<string, byte> map = (Dictionary<string, byte>)result;
                oprot.WriteMapBegin(new TMap(TType.String, TType.Byte, map.Count));
                foreach (string key in map.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteByte(map[key]);
                }
                oprot.WriteMapEnd();
            }
            if (result is Dictionary<string, bool>)
            {
                Dictionary<string, bool> map = (Dictionary<string, bool>)result;
                oprot.WriteMapBegin(new TMap(TType.String, TType.Bool, map.Count));
                foreach (string key in map.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteBool(map[key]);
                }
                oprot.WriteMapEnd();
            }
            if (result is Dictionary<string, double>)
            {
                Dictionary<string, double> map = (Dictionary<string, double>)result;
                oprot.WriteMapBegin(new TMap(TType.String, TType.Double, map.Count));
                foreach (string key in map.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteDouble(map[key]);
                }
                oprot.WriteMapEnd();
            }
        }

    }
}
2.引用远程服务类:

using System.Collections.Generic;
using Thrift.Collections;
using Thrift.Protocol;
using Thrift;
using System;

namespace saf.cshap.client
{
    public class ServiceGet
    {
        public ServiceGet(TProtocol prot)
            : this(prot, prot)
        {

        }

        public ServiceGet(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_; }
        }

        public dynamic callService(string method, dynamic[] para)
        {
            Write(method, para);
            return Read(method);
        }

        protected void Write(string method, dynamic[] para)
        {
            oprot_.WriteMessageBegin(new TMessage(method, TMessageType.Call, seqid_));
            Write(method, para, oprot_);
            oprot_.WriteMessageEnd();
            oprot_.Transport.Flush();
        }

        protected void Write(string method, dynamic[] para, TProtocol oprot)
        {
            TStruct struc = new TStruct(method + "_args");
            oprot.WriteStructBegin(struc);
            if (para != null && para.Length > 0)
            {
                TField field = new TField();
                field.Name = "para";
                field.ID = 1;
                for (int i = 0; i < para.Length; i++)
                {
                    writeField(field, para[i], oprot);
                }
            }
            oprot.WriteFieldStop();
            oprot.WriteStructEnd();
        }

        protected void writeField(TField field, dynamic para, TProtocol oprot)
        {
            if (para is System.String)
            {
                field.Type = TType.String;
                oprot.WriteFieldBegin(field);
                oprot.WriteString(para);
                oprot.WriteFieldEnd();
            }
            else if (para is System.Boolean)
            {
                field.Type = TType.Bool;
                oprot.WriteFieldBegin(field);
                oprot.WriteBool(para);
                oprot.WriteFieldEnd();
            }
            else if (para is System.Int32)
            {
                field.Type = TType.I32;
                oprot.WriteFieldBegin(field);
                oprot.WriteI32(para);
                oprot.WriteFieldEnd();
            }
            else if (para is System.Int16)
            {
                field.Type = TType.I16;
                oprot.WriteFieldBegin(field);
                oprot.WriteI16(para);
                oprot.WriteFieldEnd();
            }
            else if (para is System.Int64)
            {
                field.Type = TType.I64;
                oprot.WriteFieldBegin(field);
                oprot.WriteI64(para);
                oprot.WriteFieldEnd();
            }
            else if (para is System.Byte)
            {
                field.Type = TType.Byte;
                oprot.WriteFieldBegin(field);
                oprot.WriteByte(para);
                oprot.WriteFieldEnd();
            }
            else if (para is System.Double)
            {
                field.Type = TType.Double;
                oprot.WriteFieldBegin(field);
                oprot.WriteDouble(para);
                oprot.WriteFieldEnd();
            }
            else if (para.GetType().Name.Contains("List"))
            {
                field.Type = TType.List;
                oprot.WriteFieldBegin(field);
                writeList(field, para, oprot);
                oprot.WriteFieldEnd();
            }
            else if (para.GetType().Name.Contains("Set"))
            {
                field.Type = TType.Set;
                oprot.WriteFieldBegin(field);
                writeSet(field, para, oprot);
                oprot.WriteFieldEnd();

            }
            else if (para.GetType().Name.Contains("Dictionary"))
            {
                field.Type = TType.Map;
                oprot.WriteFieldBegin(field);
                writeMap(field, para,oprot);
                oprot.WriteFieldEnd();
            }
        }

        protected void writeList(TField field, dynamic para, TProtocol oprot)
        {
            if (para is System.Collections.Generic.List<string>)
            {
                oprot.WriteListBegin(new TList(TType.String, para.Count));
                foreach (string el in para)
                {
                    oprot.WriteString(el);
                }
                oprot.WriteListEnd();
            }
            else if (para is System.Collections.Generic.List<int>)
            {
                oprot.WriteListBegin(new TList(TType.I32, para.Count));
                foreach (int el in para)
                {
                    oprot.WriteI32(el);
                }
                oprot.WriteListEnd();
            }
            else if (para is System.Collections.Generic.List<long>)
            {
                oprot.WriteListBegin(new TList(TType.I64, para.Count));
                foreach (long el in para)
                {
                    oprot.WriteI64(el);
                }
                oprot.WriteListEnd();
            }
            else if (para is System.Collections.Generic.List<short>)
            {
                oprot.WriteListBegin(new TList(TType.I16, para.Count));
                foreach (short el in para)
                {
                    oprot.WriteI16(el);
                }
                oprot.WriteListEnd();
            }
            else if (para is System.Collections.Generic.List<bool>)
            {
                oprot.WriteListBegin(new TList(TType.Bool, para.Count));
                foreach (bool el in para)
                {
                    oprot.WriteBool(el);
                }
                oprot.WriteListEnd();
            }
            else if (para is System.Collections.Generic.List<byte>)
            {
                oprot.WriteListBegin(new TList(TType.Byte, para.Count));
                foreach (byte el in para)
                {
                    oprot.WriteByte(el);
                }
                oprot.WriteListEnd();
            }
            else if (para is System.Collections.Generic.List<double>)
            {
                oprot.WriteListBegin(new TList(TType.Double, para.Count));
                foreach (double el in para)
                {
                    oprot.WriteDouble(el);
                }
                oprot.WriteListEnd();
            }
        }

        protected void writeSet(TField field, dynamic para, TProtocol oprot)
        {
            if (para is THashSet<string>)
            {
                oprot.WriteSetBegin(new TSet(TType.String, para.Count));
                foreach (string el in para)
                {
                    oprot.WriteString(el);
                }
                oprot.WriteSetEnd();
            }
            else if (para is THashSet<int>)
            {
                oprot.WriteSetBegin(new TSet(TType.I32, para.Count));
                foreach (int el in para)
                {
                    oprot.WriteI32(el);
                }
                oprot.WriteSetEnd();
            }
            else if (para is THashSet<long>)
            {
                oprot.WriteSetBegin(new TSet(TType.I64, para.Count));
                foreach (long el in para)
                {
                    oprot.WriteI64(el);
                }
                oprot.WriteSetEnd();
            }
            else if (para is THashSet<short>)
            {
                oprot.WriteSetBegin(new TSet(TType.I16, para.Count));
                foreach (short el in para)
                {
                    oprot.WriteI16(el);
                }
                oprot.WriteSetEnd();
            }
            else if (para is THashSet<bool>)
            {
                oprot.WriteSetBegin(new TSet(TType.Bool, para.Count));
                foreach (bool el in para)
                {
                    oprot.WriteBool(el);
                }
                oprot.WriteSetEnd();
            }
            else if (para is THashSet<byte>)
            {
                oprot.WriteSetBegin(new TSet(TType.Byte, para.Count));
                foreach (byte el in para)
                {
                    oprot.WriteByte(el);
                }
                oprot.WriteSetEnd();
            }
            else if (para is THashSet<double>)
            {
                oprot.WriteSetBegin(new TSet(TType.Double, para.Count));
                foreach (double el in para)
                {
                    oprot.WriteDouble(el);
                }
                oprot.WriteSetEnd();
            }

        }

        protected void writeMap(TField field, dynamic para, TProtocol oprot)
        {
            if (para is Dictionary<string, string>)
            {
                oprot.WriteMapBegin(new TMap(TType.String, TType.String, para.Count));
                foreach (string key in para.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteString(para[key]);
                }
                oprot.WriteMapEnd();
            }
            if (para is Dictionary<string, int>)
            {
                oprot.WriteMapBegin(new TMap(TType.String, TType.I32, para.Count));
                foreach (string key in para.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteI32(para[key]);
                }
                oprot.WriteMapEnd();
            }
            if (para is Dictionary<string, long>)
            {
                oprot.WriteMapBegin(new TMap(TType.String, TType.I64, para.Count));
                foreach (string key in para.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteI64(para[key]);
                }
                oprot.WriteMapEnd();
            }
            if (para is Dictionary<string, short>)
            {
                oprot.WriteMapBegin(new TMap(TType.String, TType.I16, para.Count));
                foreach (string key in para.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteI16(para[key]);
                }
                oprot.WriteMapEnd();
            }
            if (para is Dictionary<string, byte>)
            {
                oprot.WriteMapBegin(new TMap(TType.String, TType.Byte, para.Count));
                foreach (string key in para.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteByte(para[key]);
                }
                oprot.WriteMapEnd();
            }
            if (para is Dictionary<string, bool>)
            {
                oprot.WriteMapBegin(new TMap(TType.String, TType.Bool, para.Count));
                foreach (string key in para.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteBool(para[key]);
                }
                oprot.WriteMapEnd();
            }
            if (para is Dictionary<string, double>)
            {
                oprot.WriteMapBegin(new TMap(TType.String, TType.Double, para.Count));
                foreach (string key in para.Keys)
                {
                    oprot.WriteString(key);
                    oprot.WriteDouble(para[key]);
                }
                oprot.WriteMapEnd();
            }
        }

        protected dynamic Read(string method)
        {
            TMessage msg = iprot_.ReadMessageBegin();
            if (msg.Type == TMessageType.Exception)
            {
                TApplicationException x = TApplicationException.Read(iprot_);
                iprot_.ReadMessageEnd();
                throw x;
            }
            dynamic result = null;
            bool flag = true;
            while (flag)
            {
                try { result = readField(TType.Stop, iprot_); }
                catch
                {
                    flag = false;
                }
            }
            iprot_.ReadMessageEnd();
            if (result != null)
            {
                return result;
            }
            throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, method + " failed: result = null!");
        }

        protected dynamic readField(TType type, TProtocol iprot)
        {
            iprot.ReadStructBegin();
            dynamic para = null;
            TField field;
            field = iprot.ReadFieldBegin();
            if (type == TType.Stop)
            {
                type = field.Type;
                switch (type)
                {
                    case TType.Stop: throw new Exception();

                    case TType.String: para = iprot.ReadString(); break;

                    case TType.Bool: para = iprot.ReadBool(); break;

                    case TType.Byte: para = iprot.ReadByte(); break;

                    case TType.Double: para = iprot.ReadDouble(); break;

                    case TType.I16: para = iprot.ReadI16(); break;

                    case TType.I32: para = iprot.ReadI32(); break;

                    case TType.I64: para = iprot.ReadI64(); break;

                    case TType.List:
                        TList list = iprot.ReadListBegin();
                        para = readTList(list, iprot);
                        iprot.ReadListEnd();
                        break;
                    case TType.Set:
                        TSet set = iprot.ReadSetBegin();
                        para = readTSet(set, iprot);
                        iprot.ReadSetEnd();
                        break;
                    case TType.Map:
                        TMap map = iprot.ReadMapBegin();
                        Dictionary<dynamic, dynamic> pmap = new Dictionary<dynamic, dynamic>();
                        for (int i = 0; i < map.Count; i++)
                        {
                            var key = readField(map.KeyType, iprot);
                            var value = readField(map.ValueType, iprot);
                            pmap[key] = value;
                        }
                        para = pmap;
                        iprot.ReadMapEnd();
                        break;
                    default:
                        TProtocolUtil.Skip(iprot, type); break;
                }
                iprot.ReadFieldEnd();
            }
            iprot.ReadStructEnd();
            return para;
        }

        protected dynamic readTList(TList list, TProtocol iprot)
        {
            TType type = list.ElementType;
            dynamic para = null;
            switch (type)
            {
                case TType.String:
                    para = new List<string>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(list.ElementType, iprot));
                    }
                    break;
                case TType.I32:
                    para = new List<int>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(list.ElementType, iprot));
                    }
                    break;
                case TType.I16:
                    para = new List<short>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(list.ElementType, iprot));
                    }
                    break;
                case TType.I64:
                    para = new List<long>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(list.ElementType, iprot));
                    }
                    break;
                case TType.Bool:
                    para = new List<bool>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(list.ElementType, iprot));
                    }
                    break;
                case TType.Byte:
                    para = new List<byte>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(list.ElementType, iprot));
                    }
                    break;
                case TType.Double:
                    para = new List<double>();
                    for (int i = 0; i < list.Count; i++)
                    {
                        para.Add(readField(list.ElementType, iprot));
                    }
                    break;
            }
            return para;
        }

        protected dynamic readTSet(TSet set, TProtocol iprot)
        {
            TType type = set.ElementType;
            dynamic para = null;
            switch (type)
            {
                case TType.String:
                    para = new THashSet<string>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(set.ElementType, iprot));
                    }
                    break;
                case TType.I32:
                    para = new THashSet<int>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(set.ElementType, iprot));
                    }
                    break;
                case TType.I16:
                    para = new THashSet<short>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(set.ElementType, iprot));
                    }
                    break;
                case TType.I64:
                    para = new THashSet<long>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(set.ElementType, iprot));
                    }
                    break;
                case TType.Bool:
                    para = new THashSet<bool>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(set.ElementType, iprot));
                    }
                    break;
                case TType.Byte:
                    para = new THashSet<byte>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(set.ElementType, iprot));
                    }
                    break;
                case TType.Double:
                    para = new THashSet<double>();
                    for (int i = 0; i < set.Count; i++)
                    {
                        para.Add(readField(set.ElementType, iprot));
                    }
                    break;
            }
            return para;
        }
    }
}

3.测试类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thrift.Transport;
using Thrift.Protocol;
using com.jd.saf;
using System.Collections;
using Thrift;
using Thrift.Server;
using System.IO;
using saf.cshap.client;

namespace com.jd.saf
{
    class MainClass
    {

        static void Main(string[] args)
        {
          ///  new Client().readPropertiesMap("D:/新版saf/C++/ConsoleApplication1/ConsoleApplication1/log4j.properties");
          ///   new Client().testDNS("erpcd.360buy.com");
         /// string[] ips = DNSUtils.Hostname2iplist("www.360buy.com");
         /// foreach (string ip in ips)
         /// {
         ///     Console.WriteLine(ip);
         /// }
           // Console.WriteLine(DNSUtils.Hostname2ip("www.localhost.com"));//www.12306.cn
         ///   Console.ReadKey();
         ///   new MainClass().thriftServer();
           ///MainClass.showMethods();
          // MainClass.testReflectMethods();
         // testSplit();
         //testThriftClient();
            testSafClient();
        }

        static void testSplit() {
            string ss = "www.localhost.com,www.12306.cn";
            foreach(string s in ss.Split(','))
            {
                Console.WriteLine(s);
            }
            Console.ReadKey();
        }

        public static void testThriftClient()
        {
            TTransport transport = new TSocket("localhost", 7911);

            TProtocol protocol = new TBinaryProtocol(transport);

            Hello.Client client = new Hello.Client(protocol);

            transport.Open();

            string val = client.helloString("C# client");
            Console.WriteLine(val);

            try
            {
                client.helloNull();
            }
            catch (Exception e)
            {
                Console.WriteLine("正常的异常" + e.Message);
            }

            int i = 8;
            i = client.helloInt(i);
            Console.WriteLine("i=" + i);
            bool b = client.helloBoolean(true);
            Console.WriteLine("b=" + b);

            transport.Close();
            ///Console.ReadLine();
            Console.ReadKey();
        }

        public void readProperties(String path)
        {
            PropertyFileOperator opt = new PropertyFileOperator(path);
            string value = opt.GetPropertiesText("key1");
            opt.Close();
            Console.WriteLine("value = " + value);
            Console.ReadKey();
        }

        public void readPropertiesMap(String path)
        {
            PropertyFileOperator opt = new PropertyFileOperator(path);
            Hashtable table = opt.GetProperties();
            foreach(DictionaryEntry de in table)
            {
               Console.WriteLine(de.Key);///de.Key对应于keyvalue键值对key
               Console.WriteLine(de.Value);///de.Key对应于keyvalue键值对value
            }
            opt.Close();
            Console.ReadKey();
        }

        public void testDNS(String host)
        {
            ResloveDNS dns = new ResloveDNS();
            dns.Resolve(host);
            ///Console.WriteLine(dns.IPLength);
            ///Console.WriteLine(dns.);
            ///Console.ReadKey();
        }

        public void thriftServer()
        {
            TServerSocket transport = new TServerSocket(7911,0,false);
           /// TTransport tt = new TFramedTransport(new TSocket("localhost", 10005));
           /// TBinaryProtocol tp = new TBinaryProtocol(tt);
            Hello.Processor processor = new Hello.Processor(new HelloImpl());
            TServer server = new TSimpleServer(processor, transport);
            Console.WriteLine("Starting server on port 7911 ...");
            server.Serve();           
        }

        public static void showMethods()
        {
            SafProcesser pro = new SafProcesser();
            pro.service = new MyHelloImpl();
            System.Reflection.MethodInfo[] methods = pro.service.GetType().GetMethods();
            foreach (System.Reflection.MethodInfo m in methods)
            {
                Console.WriteLine("m.Name = " + m.Name);
            }
            Console.ReadKey();
        }

        public static void testReflectMethods()
        {
            TServerSocket transport = new TServerSocket(7911, 0, false);
            SafProcesser processor = new SafProcesser();
            ///用户自己的服务类
            processor.service = new MyHelloImpl();
            TServer server = new TSimpleServer(processor, transport);
            Console.WriteLine("Starting server on port 7911 ...");
            server.Serve();
        }

        public static void testSafClient()
        {
            TTransport transport = new TSocket("localhost", 7911);
            TProtocol protocol = new TBinaryProtocol(transport);
            ServiceGet clientService = new ServiceGet(protocol);
            transport.Open();
            int start = DateTime.Now.Millisecond;
            Console.WriteLine("start = " + DateTime.Now);
            try
            {
                string s = clientService.callService("helloNull", null);
                Console.WriteLine(s);
            }
            catch (Exception e)
            {
                Console.WriteLine("正常的异常" + e.Message);
            }
            var v = clientService.callService("helloString", new dynamic[] { "C# client" });
            Console.WriteLine(v);
            int i = 8;
            i = clientService.callService("helloInt", new dynamic[] { i });
            Console.WriteLine("i=" + i);
            bool b = clientService.callService("helloBoolean", new dynamic[] { true }); ;
            Console.WriteLine("b=" + b);
            Console.WriteLine("end = " + DateTime.Now);
            Console.WriteLine("持续时间: " + (DateTime.Now.Millisecond - start) + "毫秒");
            transport.Close();
            Console.ReadKey();
        }
    }   
}

分享到:
评论

相关推荐

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

    3. **C#实现**:同样地,Thrift在C#中也会生成客户端和服务端的代码。客户端代码提供了调用远程服务的方法,而服务端代码则可以与Golang的服务端建立连接,进行反向调用。 4. **通信协议**:Thrift支持多种传输协议...

    基于Thrift框架的数据交换方案_梁明炯.pdf

    **基于Thrift的数据交换方案:** 在构建数据交换方案时,通常分为客户端和服务端两部分。服务端响应客户端的请求,而客户端通过调用服务端的方法发送或接收数据。Thrift确保客户端和服务器端的数据结构和接口一致,...

    thrift操作Hbase数据库

    首先,我们需要在Hbase服务器上安装并配置Thrift服务,然后在客户端(这里是C#应用)中引用Thrift生成的Hbase接口库。Thrift的IDL(Interface Description Language)文件定义了与Hbase交互的协议,包括表的操作、行...

    thrift安装

    Facebook的scribe日志收集系统也是基于Thrift构建的。 总的来说,Thrift是一个强大且灵活的工具,它在各种跨语言通信场景中都展现出了优秀的性能和便利性。通过理解Thrift的工作原理和安装过程,你可以更好地利用它...

    Thrift框架使用分享

    Thrift框架通过接口描述语言(IDL)来定义服务,支持多种编程语言,如C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk等,并能生成相应语言的服务端和客户端代码。其传输数据采用二进制...

    thrift例子

    它使用二进制协议,比基于文本的JSON或XML更加紧凑和快速。 6. **多语言支持**:Thrift的一大优势在于其跨语言的能力。除了Java,Thrift还支持C++、Python、PHP、C#、Ruby等多种语言,使得服务可以在各种平台和环境...

    thrift源码+DEMO+简单教程

    客户端同样基于生成的代码,创建连接,实例化服务代理并调用服务方法: ```java TTransport transport = new TSocket("localhost", 9090); TProtocol protocol = new TBinaryProtocol(transport); MyService.Client...

    thrift-0.11.0.tar.gz

    5. **客户端和服务器端库**:在解压后的`thrift-0.11.0`文件夹中,你会发现为每种支持的语言都提供了相应的客户端和服务器端库,这些库实现了编译器生成的代码,方便开发者快速构建服务。 6. **编译器工具**:...

    thrift介绍与实践

    2. **高性能**:Thrift通过编译IDL文件生成相应的代码,这些代码实现了高效的序列化和反序列化机制,以及基于TCP/IP或HTTP的网络通信协议,确保了服务之间的高速数据交换。 3. **轻量级**:Thrift的设计目标是简单...

    thrift with memfunc and uid generator

    1. **Thrift**:服务的实现和通信基于Thrift框架。 2. **UID**:服务可能涉及生成和管理uid,与描述中的uid generator对应。 3. **REST**:可能有RESTful API的设计,允许通过HTTP协议与Thrift服务进行交互,这样...

    thrift-0.9.3

    在“thrift-0.9.3”这个特定的版本中,我们拥有的是代码生成引擎,它能够自动生成各种编程语言的客户端和服务器端代码,使得开发人员可以快速地实现跨平台的服务交互。 Thrift 的工作流程分为以下几个关键步骤: 1...

    FileTransferThrift:Thrift的文件传输服务器和客户端,使用Java实现

    `FileTransferThrift` 是一个基于Thrift框架实现的文件传输服务,它使用Java编程语言进行开发。Thrift是一种高效的、跨语言的服务开发工具,由Facebook开源,现在由Apache基金会维护。这个项目的核心目标是提供一个...

    thrift相关

    2. 高效:通过二进制协议和优化的传输机制,Thrift提供了比基于XML或JSON的RPC方案更高的性能。 3. 易于使用:使用IDL定义服务,简化了服务开发和维护的复杂性。 4. 安全:由于Thrift支持自定义的安全策略,可以在...

    Apache Thrift说明

    Thrift 使用高效的二进制协议进行数据传输,相比 XML 和 JSON,它在性能和数据大小上有显著优势,特别适合大数据量和高并发的场景。 在数字化车间项目中,Thrift 可以用于处理大量固定格式的数据交换,特别是在 C#,...

    thrfit-demo

    "thrfit-demo" 是一个基于 Thrift 的示例项目,旨在帮助开发者理解和使用 Thrift。 在 "thrfit-demo" 中,我们通常会经历以下几个关键步骤: 1. **定义服务接口**:使用 Thrift IDL(Interface Description ...

    archive_ Thrift服务开发框架 v0.16.0 [江西新余电信].zip.zip

    4. **编码/序列化**: Thrift使用高效的二进制编码,比基于XML的序列化更节省带宽和内存。 5. **服务框架**: 自动生成的代码包含服务端和客户端的实现,使得开发者可以快速实现服务的业务逻辑,而无需关心底层通信...

    thriftpy-0.3.9.tar.gz

    而thriftpy是Python社区对Thrift的实现,它为Python开发者提供了方便、高效的接口来使用Thrift协议。在本文中,我们将详细探讨thriftpy-0.3.9这个版本,以及如何利用它进行服务间的通信。 一、Thrift简介 Thrift是...

    远程调用

    7. **Thrift**:Facebook开发的跨语言服务开发框架,它定义了一种接口定义语言(IDL),可以生成多语言的客户端和服务端代码,支持C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk等...

Global site tag (gtag.js) - Google Analytics