ios telegram
Mirror of hubo.dev
TCP is the only active MTProto transport on Telegram-iOS as I explained in the previous post. Let’s continue with the implementation details of connection management for MTProto.
牛逼 CP是电报,iOS的唯一活动MTProto运输正如我在以前的帖子解释。 让我们继续进行MTProto连接管理的实现细节。
The major parts of network code reside in modules TelegramCore
and MTProtoKit
. I started my reading to answer a simple question:
网络代码的主要部分位于模块TelegramCore
和MTProtoKit
。 我开始阅读以回答一个简单的问题:
How many connections are used by MTProtoKit during the first login process?
MTProtoKit在首次登录过程中使用了多少个连接?
The result surprised me: 20
TCP connections to Telegram data centers and 8
HTTPS requests to external services. The common best practice should be using as few connections as possible.
结果使我感到惊讶:与电报数据中心的20
TCP连接和与外部服务的8
HTTPS请求。 常见的最佳做法是使用尽可能少的连接。
Before diving into the code to reveal the reason, please let me introduce some important concepts.
在深入研究代码以揭示原因之前,请让我介绍一些重要的概念。
1.连接的基本概念 (1. Basic Concepts of Connections)
数据中心 (Data Center)
Telegram divides its backend servers into 5 data centers. Each has an id and an alias. Alias is useful to compose URIs for HTTP transport, which is not used in the iOS app. Telegram backend associates a registered account to a master DC id. It requires the client to use the correct master data center to access the user data and might use other DC ids to download images, files, etc.
Telegram将其后端服务器分为5个数据中心。 每个都有一个ID和一个别名。 别名对于撰写用于HTTP传输的URI很有用,iOS应用程序中未使用。 电报后端将注册帐户与主DC ID相关联。 它要求客户端使用正确的主数据中心来访问用户数据,并且可能使用其他DC ID来下载图像,文件等。
DDC 2, venusDC 3, auroraDC 4, vestaDC 5, flora
DDC 2,金星DC 3,极光DC 4,vestaDC 5,菌群
Each data center can be connected via multiple IP addresses. It’s common to NOT use domain names directly due to several reasons:
每个数据中心可以通过多个IP地址连接。 由于以下几个原因,通常不直接使用域名是很常见的:
The system DNS service might be unstable, or even untrustful.
系统DNS服务可能不稳定,甚至不可信 。
- IP addresses and ports need to change frequently to react to network issues. Static IPs could be inaccessible in some regions. Then elastic IPs could be deployed to proxy traffic to data centers. The app should be able to update its endpoint configuration in time. IP地址和端口需要经常更改以对网络问题做出React。 在某些地区可能无法访问静态IP。 然后可以部署弹性IP,以代理到数据中心的流量。 该应用程序应该能够及时更新其端点配置。
- Solutions like Geo DNS is good for very coarse-grained IP selection. It’s better for the backend to control it directly. Geo DNS之类的解决方案非常适合粗粒度的IP选择。 后端最好直接控制它。
Telegram-iOS includes several seed addresses for a cold start:
Telegram-iOS包括几个用于冷启动的种子地址:
Telegram owns four AS numbers to announce the IPs: AS62014, AS62041, AS59930, and AS44907. More static IPs can be found by searching with the AS numbers if you’re interested in it.
Telegram拥有四个用于发布IP的AS号: AS62014 , AS62041 , AS59930和AS44907 。 如果您感兴趣,可以通过搜索AS号找到更多静态IP。
端点发现 (Endpoint Discovery)
Telegram-iOS can update endpoints from internal and external services. The approaches work as complementary to others to maximize the success rate of updating. The result is persisted in Keychain with key datacenterAddressSetById
.
Telegram-iOS可以从内部和外部服务更新端点。 这些方法与其他方法互补,可以最大程度地提高更新的成功率。 结果通过键datacenterAddressSetById
在钥匙串中。
DNS-over-HTTPS via the JSON API from Google Public DNS.
tapv3.stel.com
is the hostname to resolve, and the parameterrandom_padding
is set to prevent possible side-channel attacks. An example of request and response is below:通过Google Public DNS中的JSON API通过HTTPS进行DNS转换 。
tapv3.stel.com
是要解析的主机名,并且将参数random_padding
设置为可以防止可能的旁通道攻击。 请求和响应的示例如下:
Google service responds with several DNS TXT records, that can be merged and transformed into a valid base64 string. The client has the RSA public key to decode the data and deserialize it into a list of MTBackupDatacenterAddress
.
Google服务以多个DNS TXT记录作为响应,这些记录可以合并并转换为有效的base64字符串 。 客户端具有RSA公钥以解码数据并将其反序列化为MTBackupDatacenterAddress
列表。
There is a trick inside the code. Besides a normal request to "dns.google.com"
, another request is sent to "https://www.google.com/resolve"
with the Host
header being set to "dns.google.com"
. It looks like it’s doing domain fronting to a subdomain of Google, which makes the DNS request pretend to be visiting Google Search. If you check the commit history, domain fronting was used on other self-owned domains: dns-telegram.appspot.com
and tcdnb.azureedge.net
. It became obsolete as the technique is not supported anymore.
代码内部有一个窍门。 除了对"dns.google.com"
的正常请求外, "dns.google.com"
另一个请求发送到"https://www.google.com/resolve"
,并将“ Host
标头设置为"dns.google.com"
。 看起来它正在将域名转发到Google的子域,这使DNS请求假装正在访问Google搜索。 如果您检查提交历史记录,则在其他自有域上使用了域前沿: dns-telegram.appspot.com
和tcdnb.azureedge.net
。 由于不再支持该技术,它已过时。
DNS-over-HTTPS via Cloudflare. The implementation is similar to the Google solution.
通过Cloudflare通过HTTPS进行DNS传输。 实施类似于Google解决方案。
CloudKit data. For logged-in users, the same encrypted data can be fetched from CloudKit according to phone numbers.
CloudKit数据。 对于登录用户,可以根据电话号码从CloudKit提取相同的加密数据。
help.getConfig method in MTProto. If the client is able to connect to any data center, this RPC can fetch a configuration that includes a list of
DcOption
.MTProto中的help.getConfig方法。 如果客户端能够连接到任何数据中心,则此RPC可以获取包含
DcOption
列表的DcOption
。iOS PushKit and UserNotifications. The payload inside a remote notification can include one endpoint data of a data center.
iOS PushKit和UserNotifications 。 远程通知中的有效负载可以包括数据中心的一个端点数据 。
MTProto代理 (MTProto Proxy)
Besides the normal endpoints that are operated by Telegram’s engineering team, Telegram builds a crowdsourced proxy system, which allows 3rd-party servers to proxy its traffic. Proxy providers are able to show promoted channels to users in exchange. The official proxy code is open-sourced.
除了由Telegram的工程团队操作的普通端点之外,Telegram还构建了众包代理系统 ,该系统允许第三方服务器代理其流量。 代理提供者可以向用户显示提升的频道作为交换。 官方代理代码是开源的 。
As a reverse proxy that doesn’t introduce additional protocol changes, it’s basically the same as the official endpoints from the client’s perspective.
作为不引入其他协议更改的反向代理,从客户端的角度来看,它与官方端点基本相同。
连接秘密 (Connection Secret)
Along with IP and port for a datacenter address, an optional parameter secret
is present to indicate how the client encrypts TCP connections. Please note that it’s a different concept from the message encryption of MTProto. It’s designed to obfuscate the network traffic, which helps counter DPI (Deep Packet Inspection).
除数据中心地址的IP和端口外,还提供一个可选的参数secret
,以指示客户端如何加密TCP连接。 请注意,这与MTProto的消息加密不同 。 它旨在混淆网络流量,这有助于应对DPI(深度数据包检测) 。
There are four possible types of the secret:
秘密有四种可能的类型:
nil
. No special obfuscation is applied.nil
。 没有应用特殊的混淆。MTProxySecretType0
. It’s a16 bytes secret to transmission the packets like random data. Although the packet structure is hidden, there are still statistical patterns that could be detected by DPI.MTProxySecretType0
。 像随机数据一样传输数据包是16字节的秘密。 尽管包结构是隐藏的,但仍有一些DPI可检测到的统计模式。MTProxySecretType1
. It’s decoded from a 17 bytes data. The first byte is always0xdd
, and the other 16 bytes are the secret. A padded intermediate format is applied to hide the packet pattern.MTProxySecretType1
。 它是从17个字节的数据中解码出来的。 第一个字节始终为0xdd
,其他16个字节为机密。 应用填充的中间格式来隐藏数据包模式。MTProxySecretType2
. It enables fake-TLS that turns a Telegram connection look like a TLS v1.2 connection. The data starts with a byte0xee
. The following 16 bytes are the secret data. The rest bytes is a UTF-8 encoded string, which is the SNI domain to use during a TLS handshake.MTProxySecretType2
。 它启用了伪造的TLS,从而使电报连接看起来像TLS v1.2连接。 数据以字节0xee
。 接下来的16个字节是机密数据。 其余字节是UTF-8编码的字符串,它是TLS握手期间要使用的SNI域。
Let’s take a shared URL of an MTProto proxy as an example. It declares its secret is MTProxySecretType2
as the string starts with ee
. The secret data is filled with zeros and the faked domain is itunes.apple.com
.
让我们以MTProto代理的共享URL为例。 由于字符串以ee
开头,因此声明其秘密为MTProxySecretType2
。 机密数据用零填充,伪造的域是itunes.apple.com
。
连接选择 (Connection Selection)
As one data center can have a set of addresses, MTContext
implements a selection policy to pick the one with the earliest failure timestamp.
由于一个数据中心可以具有一组地址,因此MTContext
实施了一种选择策略,以选择具有最早故障时间戳的地址。
数据中心授权 (Data Center Authorization)
Prior to sending MTProto messages to a data center, it’s required to finish (p, q) authorization with the target DC. It’s referred to as data center auth info inside the code.
在将MTProto消息发送到数据中心之前,需要完成对目标DC的(p,q)授权 。 它在代码中称为数据中心身份验证信息 。
用户授权 (User Authorization)
After successful verification by SMS code or other methods, the master datacenter associates a user account with the client’s auth_key_id
, which grants authorization to access the datacenter as the user. If the client wants to access other data centers with the same user account, it needs to transfer the authorization in advance.
通过SMS代码或其他方法成功验证后,主数据中心将用户帐户与客户端的auth_key_id
,后者授予授权以用户身份访问数据中心。 如果客户端要使用相同的用户帐户访问其他数据中心,则需要提前转移授权 。
回顾 (Recap)
According to the concepts, here are the requirements for the client to talk to the backend:
根据概念,这是客户端与后端对话的要求:
- The client needs to know the data center id and its addresses. 客户端需要知道数据中心ID及其地址。
- The addresses might be updated by endpoint discovery. 地址可以通过端点发现来更新。
- Telegram supports a special reverse proxy for MTProto. Telegram支持MTProto的特殊反向代理。
- If an address is accessible, the client needs to finish data center authorization prior to other data transmission. 如果可以访问地址,则客户端需要在完成其他数据传输之前完成数据中心授权。
- The client should finish the user authorization with its master data center. 客户端应通过其主数据中心完成用户授权。
- Authorization transfer is required if the client needs to access other data centers with the user account. 如果客户端需要使用用户帐户访问其他数据中心,则需要授权转移。
2.代码结构 (2. Code Structure)
Let’s check how Telegram-iOS organizes the code. It’s illustrated by the diagram below:
让我们检查一下Telegram-iOS如何组织代码。 如下图所示:

There is a dependency chain that gives a UI controller access to the network modules. Most controllers depend on a data model of an account, it’s either an instance of
Account
orUnauthorizedAccount
.有一个依赖关系链,使UI控制器可以访问网络模块。 大多数控制器取决于帐户的数据模型,它可以是
Account
的实例,也可以是UnauthorizedAccount
的实例。The account classes expose their
Network
instance fields publicly for controllers to send requests.帐户类公开公开其
Network
实例字段,以供控制器发送请求。
Network
encapsulates all interactions with module MTProtoKit and models RPC request-response pairs as Signals.Network
封装了与模块MTProtoKit的所有交互,并将RPC请求-响应对建模为Signals。
- Module MTProtoKit implements all the complex logics of endpoint information, authorization data, connection lifetime, encryption of connection and proto, etc. MTProtoKit模块实现了端点信息,授权数据,连接寿命,连接和原型加密等所有复杂逻辑。
核心MTProtoKit类 (Core MTProtoKit Classes)
MTContext
. It’s the context for most MTProtoKit classes by sharing and maintaining the important data of all data centers, such as addresses, auth info, etc. It’s not a singleton from the current design and it’s possible to have multiple instances.MTContext
。 通过共享和维护所有数据中心的重要数据(例如地址,身份验证信息等),这是大多数MTProtoKit类的上下文。与当前设计相比,这不是一个单例,并且可以有多个实例。MTProto
. It’s the core manager of messages to a specific data center.MTProto
。 它是发送到特定数据中心的消息的核心管理器。MTTcpTransport
. It manages a TCP connection. One MTProto instance can have up to one transport alive.MTTcpTransport
。 它管理TCP连接。 一个MTProto实例最多可以有一个传输活动。MTMessageService
. It’s an Objective-C protocol that defines methods to handle RPCs. An MTProto instance can have multipleMTMessageService
instances.MTMessageService
。 这是一个Objective-C协议,用于定义处理RPC的方法。 一个MTProto实例可以有多个MTMessageService
实例。
3.在首次登录过程中 (3. Inside the First Login Process)
The typical first login process has four stages: onboarding screen, phone number screen, verification code screen, and home screen. Let’s check the number of connections triggered per stage.
典型的首次登录过程分为四个阶段: 入职屏幕 , 电话号码屏幕 , 验证码屏幕和主屏幕 。 让我们检查每个阶段触发的连接数。

Several diagrams are present to illustrate the simplified workflow per stage. Please open the SVG version for the full resolution file as image compression on Medium blurs the charts. Some notes about the diagrams:
提供了一些图表来说明每个阶段的简化工作流程。 请打开全分辨率文件的SVG版本,因为“中等”上的图像压缩会使图表模糊。 有关图的一些注意事项:
- It’s simplified as many intermediate Signals and classes are omitted. 由于省略了许多中间信号和类,因此已简化。
- Orange nodes are code in Swift. 橙色节点是Swift中的代码。
- Green nodes are code in Objective-C. 绿色节点是Objective-C中的代码。
- Edges in blue represent connections created during the stage, while dotted one means a connection to request data center auth info and bold one means a connection for RPCs. 蓝色的边缘表示在此阶段创建的连接,而虚线表示请求数据中心身份验证信息的连接,而粗体表示表示RPC的连接。
- Edges in red represent HTTP requests. 红色边缘表示HTTP请求。
- Datacenter nodes in magenta are new IP addresses updated by endpoint discovery, and the black ones are seed addresses. 品红色的数据中心节点是通过端点发现更新的新IP地址,黑色的是种子地址。
入职 (Onboarding)
When the app is launched for the first time, there is no account data and no auth info for each data center. A new instance of UnAuthorizedAccount
asks MTContext
to get auth info from DC 1, 2, and 4, which creates TCP connection ① ② ③. The connections are closed once the auth action finishes.
首次启动该应用程序时,每个数据中心都没有帐户数据,也没有身份验证信息。 一个新的UnAuthorizedAccount
实例要求MTContext
从DC 1、2和4获取身份验证信息,从而创建TCP连接MTContext
。 身份验证操作完成后,连接将关闭。
It also invokes beginExplicitBackupAddressDiscovery
and starts the signal that’s set up in Network
. fetchBackupIps
combines different discovery signals and only consumes the first response with fetchConfigFromAddress
. As explained in the concepts section, it starts 4 HTTP requests: ① ② to Google, ③ to Cloudflare, and ④ to CloudKit.
它还将调用beginExplicitBackupAddressDiscovery
并启动Network
设置的信号。 fetchBackupIps
组合了不同的发现信号,并且仅使用fetchConfigFromAddress
消耗了第一个响应。 如概念部分所述,它启动4个HTTP请求:①②向Google,③到Cloudflare和④到CloudKit。
Now the auth info of DC 2 is ready with connection ②, a new TCP connection ④ is recreated with the auth info as DC 2 is coded as the default master datacenter id:
现在,DC 2的身份验证信息已准备就绪,可以进行连接②,因为DC 2被编码为默认的主数据中心ID,所以将使用身份验证信息重新创建新的TCP连接④:
In the meantime, Google DoH returns a new address 196.55.216.85
for DC 4. For any newly discovered endpoint, fetchConfigFromAddress
invokes requestDatacenterAddress
to send an RPC help.getConfig
for new configurations.
同时,Google 196.55.216.85
为DC 4返回一个新地址196.55.216.85
。对于任何新发现的端点, fetchConfigFromAddress
调用requestDatacenterAddress
来发送RPC help.getConfig
进行新配置。
As a new MTContext
is created without copying the internal data, it doesn’t know the original context might have the auth info of DC 4. It has to create TCP connection ⑤ for the auth info of DC 4, disconnect it, and then reconnect to it by another connection ⑥ to send the RPC. Connection ⑤ is redundant IMO.
由于创建了新的MTContext
而不复制内部数据 ,因此它不知道原始上下文可能具有DC 4的身份验证信息。它必须为DC 4的身份验证信息创建TCP连接⑤,然后断开连接,然后重新连接通过另一个连接到它⑥发送RPC。 连接⑤是冗余IMO。
The datacenter addresses inside the returned config from DC 4 are extracted and decoded to MTDatacenterAddressListData.
Then connection ⑥ is closed.
从DC 4返回的配置内部的数据中心地址被提取并解码为MTDatacenterAddressListData.
然后关闭连接⑥。
The original context replaces its seed datacenter address set with the new config if the new data are different and saves it into Keychain. The change is also dispatched to all listeners. There is a bug inside fetchConfigFromAddress
, currentAddressSet
is fetched from a wrong context and it’s always nil.
如果新数据不同,则原始上下文将使用新配置替换其种子数据中心地址集,并将其保存到钥匙串中。 更改也分派给所有侦听器。 里面有一个错误 fetchConfigFromAddress
, currentAddressSet
是从错误的情况下获取的,它总是零。
While one of the listeners is the MTProto that’s maintaining the active connection ④ to DC 2. It’s commanded to reset its transport and create connection ⑦ to 149.154.167.51
of DC 2.
侦听程序之一是MTProto,它保持与DC 2的活动连接④。被命令重置其传输并将连接create创建为DC 2的149.154.167.51
。
There is no user interaction so far, let’s refresh the status:
到目前为止,还没有用户交互,让我们刷新状态:
- 7 TCP connections and 4 HTTP requests are created. Connection ⑦ to DC 2 is active while others are closed. 创建了7个TCP连接和4个HTTP请求。 与DC 2的连接⑦处于活动状态,而其他闭合。
- The client has collected the auth info of DC 1, 2, 4. 客户端已经收集了DC 1、2、4的认证信息。
- The datacenter address set is updated. 数据中心地址集已更新。
输入电话号码 (Enter Phone Number)
After entering a phone number and tapping the next button, an RPC auth.sendCode
is sent through the active connection ⑦ to DC 2. It responds with PHONE_MIGRATE_5
as the account belongs to DC 5.
输入电话号码并点击下一步后,将通过活动连接sent将RPC auth.sendCode
发送到PHONE_MIGRATE_5
由于该帐户属于DC 5,因此PHONE_MIGRATE_5
响应。
The client acknowledges that DC 5 is the master instead of DC 2. It invokes initializedNetwork
and creates an instance of UnauthorizaedAccount
again to resend auth.sendAuth
to DC 5. Inside initializedNetwork
, a new MTContext
is created to support future operations.
客户端确认DC 5是主服务器,而不是auth.sendAuth
。它调用了initializedNetwork
并再次创建UnauthorizaedAccount
实例,以将auth.sendAuth
重新发送到auth.sendAuth
。在initializedNetwork
,创建了一个新的MTContext
以支持将来的操作。
As the client doesn’t have the auth info of DC 5 yet, connection ⑧ is made for it. At the same time, the new instance of UnauthorizaedAccount
unfortunately initiates the same endpoint discovery logic, which causes more unnecessary actions:
由于客户端尚没有DC 5的身份验证信息,因此将为其建立连接⑧。 同时,不幸的是,新的UnauthorizaedAccount
实例启动了相同的端点发现逻辑,这将导致更多不必要的操作:
It creates HTTP requests ④ ⑤ ⑥ ⑦ and gets the same address
196.55.216.85
of DC 4 again.它创建HTTP请求
196.55.216.85
,并再次获得DC 4的相同地址196.55.216.85
。As the MTContext inside
fetchConfigFromAddress
is unaware of the auth info of DC 4 due to the same copy issue, it creates connection ⑨ for it and ⑩ to sendhelp.getConfig
again.由于相同的复制问题,由于内部fetchConfigFromAddress内的
fetchConfigFromAddress
不了解DC 4的身份验证信息,因此会为其创建连接and,并再次创建连接help.getConfig
。The same address set is returned inside the config data. The
currentAddressSet
bug causes it to invokeupdateAddressSetForDatacenterWithId
.在配置数据中返回相同的地址集。
currentAddressSet
错误导致它调用updateAddressSetForDatacenterWithId
。The incorrect change event is propagated to the
MTProto
that has the active connection ⑧ to DC 5. It reset it and creates connection ⑪ to continue with the auth info request to DC 5.错误的更改事件将传播到具有到DC 5的活动连接
MTProto
。它将重置它并创建连接⑪以继续对DC 5的身份验证信息请求。
After having the auth info, connection ⑪ is closed and ⑫ is started to send auth.sendAuth
to DC 5.
获得身份验证信息后,连接⑪将关闭,并且started将auth.sendAuth
向DC 5发送auth.sendAuth
。
Summary for this stage:
此阶段的摘要:
- 5 TCP connections and 4 HTTP requests are created. Connection ⑫ to DC 5 and ⑦ to DC 2 are active while others are closed. The caveats of implementation have caused redundant connections and requests. 创建5个TCP连接和4个HTTP请求。 ⑫到DC 5的连接and和DC到DC 2的连接被激活,而其他开关则关闭。 实施的注意事项导致了多余的连接和请求。
- The client has auth info of DC 1, 2, 4, 5. 客户端具有DC 1、2、4、5的身份验证信息。
- The list of address set is unchanged although it’s updated again. 地址集列表没有更改,尽管它已再次更新。
BTW, if the seed addresses and the backup addresses from DoH don’t work in your network, Telegram-iOS would prompt you to set up proxies after a 20s timeout, as there is no other workaorounds at the moment.
顺便说一句,如果DoH的种子地址和备用地址在您的网络中不起作用,Telegram-iOS会在20秒超时后提示您 设置代理 ,因为目前没有其他解决方法。
输入授权码 (Enter Authorization Code)
After entering the login code received from SMS, it’s sent by RPC auth.signIn
via the active connection ⑫. DC 5 verifies it’s correct and returns auth.Authorization.authorization
. The client finally can replace its unauthorized state with a good account by calling switchToAuthorizedAccount
.
输入从SMS收到的登录代码后,它由RPC auth.signIn
通过活动连接sent发送。 DC 5验证其正确并返回auth.Authorization.authorization
。 客户端最终可以通过调用switchToAuthorizedAccount
用一个好的帐户替换其未授权状态。
After creating new Account
and Network
instances, the alive ones are destroyed and connections ⑫ and ⑦ are closed. Connection ⑬ is made with the user auth data to 91.108.56.143
of DC 5. ChatHistoryPreloadManager
also creates connection ⑭ to DC 5 to download chat histories.
创建新的Account
和Network
实例后,活动实例将被销毁,连接⑫和⑦将关闭。 连接⑬与用户身份验证数据到由91.108.56.143
DC 5. ChatHistoryPreloadManager
还创建连接到⑭DC 5到下载聊天记录 。
A bunch of RPCs are sent through ⑬ including another help.getConfig
call in function managedConfigurationUpdates
. The config from DC 5 has a different list of address sets than the one from DC 4, especially the address of DC 5 is changed to 91.108.56.156
. Connections ⑬ and ⑭ are not affected by the new config as forceUpdateSchemes
is false in managedConfigurationUpdates.
通过sent发送一堆RPC,包括在managedConfigurationUpdates
函数中的另一个help.getConfig
调用。 DC 5的配置与DC 4的配置具有不同的地址集列表,尤其是DC 5的地址更改为91.108.56.156
。 连接⑬和⑭不受新配置的影响,因为forceUpdateSchemes
为false managedConfigurationUpdates.
The home screen is ready to show with the account. Other modules start to fetch resources for the UI components, like the avatar image, etc. All requests are sent via multiplexedRequestManager
owned by account.network
. During this login session, all resources are located on DC 1.
准备好与帐户一起显示主屏幕。 其他模块开始获取UI组件的资源,例如头像图像等。所有请求都是通过account.network
拥有的multiplexedRequestManager
发送的。 在此登录会话期间,所有资源都位于DC 1上。
Before the client could download files from DC 1, it has to transfer its user authorization from DC 5 to DC 1. Connection ⑮ is created to ask DC 5 to export the auth data, connection ⑯ is made to import the data to DC 1. Both connections are closed after the job is done.
在客户端可以从DC 1下载文件之前,它必须将其用户授权从DC 5转移到DC1。创建了连接ask,要求DC 5 导出身份验证数据 ,然后进行连接to,以将数据导入 DC 1。作业完成后,两个连接均关闭。
MultiplexedRequestManagerContext
limits max to 4 workers per DC. That’s why there are connections ⑰ ⑱ ⑲ ⑳ for Download
.
MultiplexedRequestManagerContext
将每个DC最多限制为4个worker 。 这就是为什么要Download
连接why why why的原因。
4。结论 (4. Conclusion)
- During the first login process. It might not be good to have 20 TCP connections and 8 HTTP requests, although there are many tasks to finish. 在首次登录过程中。 尽管要完成许多任务,但拥有20个TCP连接和8个HTTP请求可能并不好。
- It’s possible to optimize the usage of connections and requests. 可以优化连接和请求的使用。
It requires lots of effects to make a messenger product reliably connect to its data centers. Multiple backup plans are necessary for unexpected network issues. Besides the methods used in Telegram, there are many other approaches to explore.
为了使Messenger产品可靠地连接到其数据中心,它需要很多效果。 对于意外的网络问题,必须有多个备份计划。 除了电报中使用的方法外,还有许多其他方法可以探索。
I have mixed feelings about modeling states of connections and data in a purely reactive way. The good thing is that it actually works. But it results in a complex dependency structure with many Signals. Sorting it out is not intuitive even under the help of Xcode debugger, which provides a great feature of showing recorded stack frames.
我对以纯粹的React方式对连接和数据的状态进行建模感到mixed贬不一。 好消息是它确实有效。 但这会导致具有许多信号的复杂依赖关系结构。 即使在Xcode调试器的帮助下,对其进行分类也不是直观的,它提供了显示记录的堆栈帧的强大功能。
It would be great to integrate debugging tools to help explore the running states, such as Flipper, FLEX, Timelane, etc.
翻译自: https://itnext.io/source-code-walkthrough-of-telegram-ios-part-4-mtproto-connections-22ef2e5b339
ios telegram