Api 反序列化';向量t';作为电报客户端中返回的RpcResult对象

Api 反序列化';向量t';作为电报客户端中返回的RpcResult对象,api,serialization,telegram,Api,Serialization,Telegram,对contacts.getStatus进行电报客户端方法调用时,返回值的类型为RpcResult -->('get_server_answer: method: ', 'contacts.getStatuses') <--('TL tl_elem.type: ', u'RpcResult') <--('TL deserialize: type = ', u'long') <--('TL deserialize: subtype = ', None) <

对contacts.getStatus进行电报客户端方法调用时,返回值的类型为
RpcResult

-->('get_server_answer: method: ', 'contacts.getStatuses')
<--('TL tl_elem.type: ', u'RpcResult')

<--('TL deserialize: type     =  ', u'long')
<--('TL deserialize: subtype  = ', None)

<--('TL deserialize: type     =  ', u'Object')
<--('TL tl_elem.type: ', u'Vector t')
RpcResult
定义为:

rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult;
这意味着有一个消息id和一个对象。然后,必须根据从对象的前4个字节提取的数据类型对对象进行反序列化。这很好,它适用于所有返回的
RpcResult
对象,除了一个:
contact.getStatuses

除了
对象
类型为
向量t
之外,返回的数据看起来应该是这样的

-->('get_server_answer: method: ', 'contacts.getStatuses')
<--('TL tl_elem.type: ', u'RpcResult')

<--('TL deserialize: type     =  ', u'long')
<--('TL deserialize: subtype  = ', None)

<--('TL deserialize: type     =  ', u'Object')
<--('TL tl_elem.type: ', u'Vector t')
由于前四个字节为F3 5C 6D 01(小尾端顺序),表示已返回
RpcResult
数据类型:

rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult;
这意味着我现在需要一个
long
(req\u msg\u id)和一个
对象
(result)

因此接下来的8个字节(长)应该是req_msg_id:00 E4 D0 22 AF 90 34 58

接下来的四个字节表示返回的
对象
类型:1C B5 C4 15 …这是一个
向量

vector#1cb5c415 {t:Type} # [ t ] = Vector t;
这只剩下最后四个字节,即零:00

这是否意味着向量中有零项

如果这不是零,我将如何(从字节流)确定向量中的数据类型

这是一个完整的字节流,从上一次成功的方法调用(user.getFullUser)开始,然后是方法调用,该方法调用的结果我无法反序列化(contacts.getStatuses),因为向量中的类型未标识:

('method_call: ', 'users.getFullUser', {'id': {'inputPeerSelf': {}}})
--> send_message: sending...

<-- Result:
('TL tl_elem.type: ', u'RpcResult')
('TL deserialize: type     =  ', u'long')
('TL deserialize: type     =  ', u'Object')
 0 | 01 6D 5C F3 00 F4 FD 94  <-- RpcResult (F3 5C 6D 01)
 8 | F6 F0 35 58 03 FC 32 59
16 | 00 00 00 00 9A 97 0D D1
24 | 57 04 00 00 61 1F 02 00
32 | 60 BA 2D 1C 69 6E 9F C4
40 | 05 4B 65 6E 6E 79 00 00
48 | 05 43 61 73 6F 6E 00 00
56 | 0B 31 32 30 36 35 35 30
64 | 30 30 34 39 49 39 B9 ED
72 | 06 F2 35 58 4C 48 CE 3A
80 | AD D3 ED FE 47 92 4F 5F
88 | 9A 97 0D D1 57 04 00 00
96 | 61 1F 02 00 60 BA 2D 1C
104 | 69 6E 9F C4 05 4B 65 6E
112 | 6E 79 00 00 05 43 61 73
120 | 6F 6E 00 00 0B 31 32 30
128 | 36 35 35 30 30 30 34 39
136 | 49 39 B9 ED 06 F2 35 58
144 | C0 A4 CD 9A 01 00 00 00
152 | 00 00 00 00 07 64 65 66
160 | 61 75 6C 74

('TL tl_elem.type: ', u'UserFull')
('TL deserialize: type     =  ', u'#')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', u'User')

('TL tl_elem.type: ', u'User')
('TL deserialize: type     =  ', u'#')
('TL deserialize: type     =  ', u'true')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', u'int')
('TL deserialize: type     =  ', u'long')
('TL deserialize: type     =  ', u'string')
('TL deserialize: type     =  ', u'string')
('TL deserialize: type     =  ', u'string')
('TL deserialize: type     =  ', u'UserStatus')

('TL tl_elem.type: ', u'UserStatus')
('TL deserialize: type     =  ', u'int')

('TL tl_elem.type: ', u'contacts.Link')
('TL deserialize: type     =  ', u'ContactLink')

('TL tl_elem.type: ', u'ContactLink')
('TL deserialize: type     =  ', u'ContactLink')

('TL tl_elem.type: ', u'ContactLink')
('TL deserialize: type     =  ', u'User')

('TL tl_elem.type: ', u'User')
('TL deserialize: type     =  ', u'#')
('TL deserialize: type     =  ', u'true')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', u'int')
('TL deserialize: type     =  ', u'long')
('TL deserialize: type     =  ', u'string')
('TL deserialize: type     =  ', u'string')
('TL deserialize: type     =  ', u'string')
('TL deserialize: type     =  ', u'UserStatus')

('TL tl_elem.type: ', u'UserStatus')
('TL deserialize: type     =  ', u'int')

('TL deserialize: type     =  ', u'PeerNotifySettings')
('TL tl_elem.type: ', u'PeerNotifySettings')
('TL deserialize: type     =  ', u'#')
('TL deserialize: type     =  ', u'true')
('TL deserialize: type     =  ', 'false')
('TL deserialize: type     =  ', u'int')
('TL deserialize: type     =  ', u'string')

-----------------------------------------------------
('user.getFullUser: ', 
{u'req_msg_id': 6356251390955615232L,
u'result': {u'link': 
{u'user': {u'last_name': 'Cason', u'status': {u'expires': 1479930374}, u'first_name': 'Kenny', u'bot_nochats': False, u'verified': False, 

u'bot_chat_history': False, u'min': False, u'deleted': False, u'restricted': False, u'self': True, u'bot': False, u'phone': '12069500049', 

u'contact': False, u'flags': 1111, u'bot_inline_geo': False, u'access_hash': -4278579723255301539L, u'mutual_contact': False, u'id': 139109}, 

u'my_link': {}, u'foreign_link': {}}, u'notify_settings': {u'show_previews': True, u'mute_until': 0, u'sound': 'default', u'flags': 1, u'silent': 

False}, u'flags': 0, u'user': {u'last_name': 'Cason', u'status': {u'expires': 1479930374}, u'first_name': 'Kenny', u'bot_nochats': False, 

u'verified': False, u'bot_chat_history': False, u'min': False, u'deleted': False, u'restricted': False, u'self': True, u'bot': False, u'phone': 

'12069500049', u'contact': False, u'flags': 1111, u'bot_inline_geo': False, u'access_hash': -4278579723255301539L, u'mutual_contact': False, 

u'id': 139109}, u'blocked': False}})
-----------------------------------------------------

('method_call: ', 'contacts.getStatuses', {})
--> send_message: sending...

<-- Result:
('TL tl_elem.type: ', u'RpcResult')
('TL deserialize: type     =  ', u'long')
('TL deserialize: type     =  ', u'Object')
 0 | 01 6D 5C F3 00 2C 87 B6  <-- RpcResult
 8 | F9 F0 35 58 15 C4 B5 1C
16 | 00 00 00 00
('method_call:','users.getFullUser',{'id':{'inputPeerSelf':{}})
-->发送消息:正在发送。。。

这是我用来处理向量的解码器的一部分(用Elixir编写)

您可能会得到一个简单的端到端打包的类型数组,在这种情况下,我使用
dec_o
variant,根据要解码的二进制文件的头检查预期的类型,我一直这样做,直到我从接收到的字节流中删除了给定类型的N个数字——这是我解码类型列表的方式,其中vectore头没有给出计数

第二种方法更简单,有一个前导类型头、一个向量头和一个预期项计数。在这种情况下,我调用
dec_v
变量,如下所示

希望这有助于

  defp decode([type], <<21, 196, 181, 28, cnt::little-4*8, bin::binary>>), do: dec_v(type, bin, cnt, [])
  defp decode([_typ], <<code::little-4*8, _::binary>> = bin), do: dec_o(code, bin, [])
  defp decode(_, bin), do: decode(bin)
  defp decode(bin, flag, ix) when band(flag, ix) == ix, do: decode(bin)
  defp decode(bin, _, _), do: {nil, bin}
  defp decode(type, bin, flag, ix) when band(flag, ix) == ix, do: decode(type, bin)
  defp decode(_, bin, _, _), do: {nil, bin}
  defp dec_v(_, e, 0, acc), do: {Enum.reverse(acc), e}
  defp dec_v(_,"", _, acc), do: {Enum.reverse(acc),""}
  defp dec_v(type, bin, cnt, acc) do
    {v, e} = decode(type, bin)
    dec_v(type, e, cnt - 1, [v | acc])
  end
  defp dec_o(c0, <<c1::little-4*8, _::binary>> = bin, acc) when c0 != c1, do: {Enum.reverse(acc), bin}
  defp dec_o(c0, <<c1::little-4*8, _::binary>> = bin, acc) when c0 == c1 do
    {v, e}= decode(bin)
    dec_o(c0, e, [v | acc])
  end

我很感激你的回答,但我不太擅长阅读Elixer。如果你能详细阐述一下细节,那会很有帮助的。他们在什么地方有记录吗?底线是:我收到了一个对象数据类型,该类型解码为
向量t
。我现在必须解码哪些字节来确定
t
是什么类型以及有多少个字节?这里有两种可能:相同的对象类型端到端堆叠,一个接一个,因此每个对象从其标题字段开始,当下一个标题字段更改时,您停止读取对象。第二种方法是使用一个实际向量指示符,后跟一个表示计数的4字节整数。这是直截了当的,因为您将有N个对象要从字节流中解码。我编辑了我的原始帖子,以添加从服务器返回的实际字节。正如您所看到的,它表示正在返回一个向量,并且向量中可能没有项。我可以处理这个问题,但是如果向量中有超过零的项呢?根据上述数据,没有任何信息表明这些项目的类型:-(我在上面的问题中添加了一个完整的字节流,其中包括我有一个问题的方法和之前的方法。据我所知,在
Vector t
中没有任何东西指示
t
的类型。另一件事是,运行
contacts.getContacts\22c6aa08散列:string=contac>的结果是什么。)ts.Contacts;
?如果这是一个新号码,您尚未同步/上传任何联系人,我想知道您是否确实看到了正确的结果,否?请使用您提供的数据查看下面的扩展答案谢谢,但我没有看到您的扩展答案。我缺少什么:-(我现在看到了你的答案,很抱歉我的不耐烦。你解码的字节是用于实际工作的方法,在我的问题方法之前调用的字节。很高兴你得到了相同的解码,但这没有回答问题。当你尝试解码时会发生什么:0x01 6D 5C F3 00 2C 87 B6 F9 F0 35 58 15 C4 B5 1C 00 00 00这是完整的帧吗?
0x01 6D 5C F3 00 2C 87 B6 F9 F0 35 58 15 C4 B5 1C 00 00 00
iex(4)>x=0x016D5CF3002C87B6F9F0355815C4 B51C000000000
iex(5)>TL.hex{%TL.Rpc_结果{req(请求消息id:635625404403158016,结果:%TL未知{},
Erlang/OTP 19 [erts-8.1] [64-bit] [smp:8:8] [async-threads:10]

Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> x = 0x016D5CF300F4FD94F6F0355803FC3259000000009A970DD157040000611F020060BA2D1C696E9FC4054B656E6E790000054361736F6E00000B31323036353530303034394939B9ED06F235584C48CE3AADD3EDFE47924F5F9A970DD157040000611F020060BA2D1C696E9FC4054B656E6E790000054361736F6E00000B31323036353530303034394939B9ED06F23558C0A4CD9A01000000000000000764656661756C74

iex(3)> TL.hex x
{%TL.Rpc_Result{req_msg_id: 6356251390955615232,
  result: %TL.UserFull{about: nil, blocked: nil, bot_info: nil, flags: 0,
   link: %TL.Contacts.Link{foreign_link: %TL.ContactLinkUnknown{},
    my_link: %TL.ContactLinkNone{},
    user: %TL.User{access_hash: 14168164350454250080, bot: nil,
     bot_chat_history: nil, bot_info_version: nil, bot_inline_geo: nil,
     bot_inline_placeholder: nil, bot_nochats: nil, contact: nil, deleted: nil,
     first_name: "Kenny", flags: 1111, id: 139105, last_name: "Cason", min: nil,
     mutual_contact: nil, phone: "12065500049", photo: nil, restricted: nil,
     restriction_reason: nil, self: true,
     status: %TL.UserStatusOnline{expires: 1479930374}, username: nil,
     verified: nil}},
   notify_settings: %TL.PeerNotifySettings{flags: 1, mute_until: 0,
    show_previews: true, silent: nil, sound: "default"}, profile_photo: nil,
   user: %TL.User{access_hash: 14168164350454250080, bot: nil,
    bot_chat_history: nil, bot_info_version: nil, bot_inline_geo: nil,
    bot_inline_placeholder: nil, bot_nochats: nil, contact: nil, deleted: nil,
    first_name: "Kenny", flags: 1111, id: 139105, last_name: "Cason", min: nil,
    mutual_contact: nil, phone: "12065500049", photo: nil, restricted: nil,
    restriction_reason: nil, self: true,
    status: %TL.UserStatusOnline{expires: 1479930374}, username: nil,
    verified: nil}}}, ""}