【protobuf進階】讀取proto實體裡的extensionObject物件的方法

weixin_34279184發表於2016-12-07
//設定擴充套件物件
ProtoBuf.Extensible.AppendValue
//讀取擴充套件物件
ProtoBuf.Extensible.GetValue

最近通過C#的TcpClient呼叫java伺服器介面,使用了protobuf的協議,在除錯介面的時候一直取不到extensionObject

Response.cs如下

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// Generated from: proto/Response.proto
namespace hrv
{
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"Response")]
  public partial class Response : global::ProtoBuf.IExtensible
  {
    public Response() {}
    
    private hrv.Response.Status _status;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"status", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
    public hrv.Response.Status status
    {
      get { return _status; }
      set { _status = value; }
    }

    private string _timestamp = "";
    [global::ProtoBuf.ProtoMember(2, IsRequired = false, Name=@"timestamp", DataFormat = global::ProtoBuf.DataFormat.Default)]
    [global::System.ComponentModel.DefaultValue("")]
    public string timestamp
    {
      get { return _timestamp; }
      set { _timestamp = value; }
    }

    private hrv.RespFailed _respfailed = null;
    [global::ProtoBuf.ProtoMember(100, IsRequired = false, Name=@"respfailed", DataFormat = global::ProtoBuf.DataFormat.Default)]
    [global::System.ComponentModel.DefaultValue(null)]
    public hrv.RespFailed respfailed
    {
      get { return _respfailed; }
      set { _respfailed = value; }
    }

    private hrv.RespSuccess _respSuccess = null;
    [global::ProtoBuf.ProtoMember(101, IsRequired = false, Name=@"respSuccess", DataFormat = global::ProtoBuf.DataFormat.Default)]
    [global::System.ComponentModel.DefaultValue(null)]
    public hrv.RespSuccess respSuccess
    {
      get { return _respSuccess; }
      set { _respSuccess = value; }
    }
    [global::ProtoBuf.ProtoContract(Name=@"Status")]
    public enum Status
    {
            
      [global::ProtoBuf.ProtoEnum(Name=@"OK", Value=0)]
      OK = 0,
            
      [global::ProtoBuf.ProtoEnum(Name=@"ERROR", Value=1)]
      ERROR = 1
    }
  
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
  
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"RespFailed")]
  public partial class RespFailed : global::ProtoBuf.IExtensible
  {
    public RespFailed() {}
    
    private int _code;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"code", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
    public int code
    {
      get { return _code; }
      set { _code = value; }
    }
    private string _error;
    [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"error", DataFormat = global::ProtoBuf.DataFormat.Default)]
    public string error
    {
      get { return _error; }
      set { _error = value; }
    }
    private string _errorDescription;
    [global::ProtoBuf.ProtoMember(3, IsRequired = true, Name=@"errorDescription", DataFormat = global::ProtoBuf.DataFormat.Default)]
    public string errorDescription
    {
      get { return _errorDescription; }
      set { _errorDescription = value; }
    }
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
  
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"RespSuccess")]
  public partial class RespSuccess : global::ProtoBuf.IExtensible
  {
    public RespSuccess() {}
    
    private hrv.RespSuccess.Type _type;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"type", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
    public hrv.RespSuccess.Type type
    {
      get { return _type; }
      set { _type = value; }
    }
    [global::ProtoBuf.ProtoContract(Name=@"Type")]
    public enum Type
    {
            
      [global::ProtoBuf.ProtoEnum(Name=@"LOGIN", Value=0)]
      LOGIN = 0,
            
      [global::ProtoBuf.ProtoEnum(Name=@"CHANGE_PASSWORD", Value=1)]
      CHANGE_PASSWORD = 1,
            
      [global::ProtoBuf.ProtoEnum(Name=@"RESOURCE_LIST", Value=2)]
      RESOURCE_LIST = 2,
            
      [global::ProtoBuf.ProtoEnum(Name=@"SAVE_SCALE", Value=3)]
      SAVE_SCALE = 3,
            
      [global::ProtoBuf.ProtoEnum(Name=@"UPDATE_USER_INFO", Value=4)]
      UPDATE_USER_INFO = 4,
            
      [global::ProtoBuf.ProtoEnum(Name=@"GET_SCALE_LIST", Value=5)]
      GET_SCALE_LIST = 5,
            
      [global::ProtoBuf.ProtoEnum(Name=@"GET_SCALE", Value=6)]
      GET_SCALE = 6
    }
  
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
  
}
View Code

明顯有一個private的extensionObject,但是不可訪問。

    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }

最終猜測使用如下方法獲取

var loginResp = ProtoBuf.Extensible.GetValue<LoginResp>(response.respSuccess, 100);

測試程式碼如下

            if (ConnectServer("127.0.0.1", 8998))
            {
                var reqest = new Request() { type = Request.Type.LOGIN, };
                var loginReq = new LoginReq() { username = "zhangsan", password = "123456" };
                ProtoBuf.Extensible.AppendValue<LoginReq>(reqest, 100, loginReq);

                var stream = hrvClient.GetStream();
                ProtoBuf.Serializer.SerializeWithLengthPrefix(stream, reqest, ProtoBuf.PrefixStyle.Base128);
                var response = ProtoBuf.Serializer.DeserializeWithLengthPrefix<Response>(stream, ProtoBuf.PrefixStyle.Base128);

                if (response.status == Response.Status.OK && response.respSuccess != null)
                {
                    var loginResp = ProtoBuf.Extensible.GetValue<LoginResp>(response.respSuccess, 100);

                    var result = loginResp.result;
                    var userinfo = loginResp.userInfo;
                }
                
            }

搞定!

相關文章