//設定擴充套件物件
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); } } }
明顯有一個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; } }
搞定!