MTProto移动协议关于消息的服务消息

收据确认

几乎所有消息(除少数纯粹的服务消息以及协议中用于创建授权密钥的纯文本消息外)的接收都必须得到确认。这需要使用以下服务消息(无需确认):

msgs_ack#62d6b459 msg_ids:Vector<long> = MsgsAck;

服务器通常使用 RPC 响应来确认收到来自客户端的消息(通常是 RPC 查询)。如果响应需要很长时间才能收到,服务器可能会先发送接收确认,稍后再发送 RPC 响应本身。

通常情况下,客户端会通过在下一个 RPC 查询中添加确认信息来确认收到服务器的消息(通常是 RPC 响应),前提是该确认信息发送时间不太晚(例如,在收到服务器消息后 60-120 秒内生成)。但是,如果长时间没有理由向服务器发送消息,或者服务器返回的未确认消息数量过多(例如超过 16 条),则客户端会单独发送确认信息。

每个构造函数最多允许 8192 个 ID。

忽略错误消息的通知

在某些情况下,服务器可能会通知客户端其收到的消息因某种原因被忽略。请注意,只有在服务器正确解码消息后,才能生成此类通知。

bad_msg_notification#a7eff811 bad_msg_id:long bad_msg_seqno:int error_code:int = BadMsgNotification;
bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification;

这里,error_code 还可以取以下值:

其目的是将 error_code 值分组(error_code >> 4):例如,代码 0x40 - 0x4f 对应于容器分解中的错误。

被忽略消息的通知不需要确认(即,无关紧要)。

重要提示:如果服务器上的 server_salt 值发生更改,或者客户端时间不正确,任何查询都会返回上述格式的通知。客户端必须检查其是否确实最近发送过带有指定 msg_id 的消息,如果是,则应根据 msg_id 和 server_salt 通知更新其时间校正值(客户端时钟与服务器时钟之间的差值)和服务器盐值,以便用于(重新)发送后续消息。同时,还必须使用更准确的 msg_id 和/或 server_salt 重新发送导致返回错误消息的原始消息。

此外,客户端可以根据 RPC 响应或包含 RPC 响应的容器的值来更新用于向服务器发送消息的 server_salt 值,前提是该 RPC 响应确实与最近发送的查询匹配。(如有疑问,最好不要更新,因为存在重放攻击的风险)。

请求消息状态信息

如果任何一方长时间未收到有关其外发邮件状态的信息,则可以明确地向另一方提出请求:

msgs_state_req#da69fb52 msg_ids:Vector long = MsgsStateReq;

每个构造函数最多允许 8192 个 ID。

查询结果包含以下信息:

关于消息状态的提示信息

msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;

这里info是一个字符串,其中包含来自传入 msg_ids 列表的每条消息的一个字节的消息状态:

此响应无需确认。它本身就是对相关 msgs_state_req 的确认。

请注意,如果突然发现对方遗漏了看似已发送给他们的消息,则不能使用相同的 msg_id 单独重新发送该消息。相反,可以将其包装在一个容器中,或者使用 msgs_state_req 检查消息状态。如果消息未被接收,则必须使用新的 msg_id 重新发送。

自愿沟通消息状态

任何一方均可自愿告知另一方另一方所发送消息的状态。

msgs_all_info#8cc0d131 msg_ids:Vector long info:string = MsgsAllInfo

本方已知的所有消息代码均已列出,但设置了 +128 和 +16 标志的消息代码除外。但是,如果设置了 +32 标志但未设置 +64 标志,则仍会传达消息状态。

此消息无需确认。

扩展自愿沟通状态一条消息

服务器通常使用此消息来响应重复的 msg_id,尤其是在已经生成对该消息的响应且响应内容较大的情况下。如果响应内容较小,服务器可能会直接重新发送响应。此消息也可以用作通知,而不是重新发送大型消息。

msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo;

第二个版本用于通知服务器上创建的消息(例如新消息通知),这些消息并非响应 RPC 查询而创建,并且已在一段时间前传输到客户端,但尚未得到确认。

目前status该值始终为零。未来可能会发生变化。

此消息无需确认。

明确请求重新发送消息

msg_resend_req#7d861a08 msg_ids:Vector long = MsgResendReq;

远程方会立即响应,重新发送请求的消息,通常使用与发送查询时相同的连接。如果至少有一条具有请求的 msg_id 的消息不存在、已被遗忘,或已被请求方发送(根据奇偶校验可知),则会为所有请求的消息返回 MsgsStateInfo,就好像 MsgResendReq 查询本身也是 MsgsStateReq 查询一样。
每个构造函数最多允许 8192 个 ID。