【protobuf进阶】读取proto实体里的extensionObject对象的方法

时间:2023-03-09 19:51:52
【protobuf进阶】读取proto实体里的extensionObject对象的方法
//设置扩展对象
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(, 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(, 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(, 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(, 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=)]
OK = , [global::ProtoBuf.ProtoEnum(Name=@"ERROR", Value=)]
ERROR =
} 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(, IsRequired = true, Name=@"code", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
public int code
{
get { return _code; }
set { _code = value; }
}
private string _error;
[global::ProtoBuf.ProtoMember(, IsRequired = true, Name=@"error", DataFormat = global::ProtoBuf.DataFormat.Default)]
public string error
{
get { return _error; }
set { _error = value; }
}
private string _errorDescription;
[global::ProtoBuf.ProtoMember(, 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(, 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=)]
LOGIN = , [global::ProtoBuf.ProtoEnum(Name=@"CHANGE_PASSWORD", Value=)]
CHANGE_PASSWORD = , [global::ProtoBuf.ProtoEnum(Name=@"RESOURCE_LIST", Value=)]
RESOURCE_LIST = , [global::ProtoBuf.ProtoEnum(Name=@"SAVE_SCALE", Value=)]
SAVE_SCALE = , [global::ProtoBuf.ProtoEnum(Name=@"UPDATE_USER_INFO", Value=)]
UPDATE_USER_INFO = , [global::ProtoBuf.ProtoEnum(Name=@"GET_SCALE_LIST", Value=)]
GET_SCALE_LIST = , [global::ProtoBuf.ProtoEnum(Name=@"GET_SCALE", Value=)]
GET_SCALE =
} 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, );

测试代码如下

            if (ConnectServer("127.0.0.1", ))
{
var reqest = new Request() { type = Request.Type.LOGIN, };
var loginReq = new LoginReq() { username = "zhangsan", password = "" };
ProtoBuf.Extensible.AppendValue<LoginReq>(reqest, , 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, ); var result = loginResp.result;
var userinfo = loginResp.userInfo;
} }

搞定!