与不同数据中心合作
服务器被划分为多个数据中心(以下简称“DC”),分布在世界不同地区。 这些DC的完整代理接入点列表可通过help.getConfig获取:
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true this_port_only:flags.5?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption; config#cc1a241e flags:# default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true force_try_ipv6:flags.14?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int channels_read_media_period:int tmp_sessions:flags.0?int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int reactions_default:flags.15?Reaction autologin_token:flags.16?string = Config; ---functions--- help.getConfig#c4f9186b = Config;
在此语境中,this_dc是当前 DC 的编号,dc_options是当前所有可用 DC 的列表,每个 DC 都有ID、IP和端口用于建立连接。请注意,IP和端口可能会根据代理服务器负载和用户当前位置频繁变化。
通常,每个数据中心至少有一个IPv4和一个IPv6端点可用。
为了优化客户端与API的通信,每个客户端必须使用与最近接入点的连接来进行其主要查询(发送消息、获取联系人等)。因此,在与API通信之前,必须知道如何选择DC。
注册/授权
auth.sendCode 方法是注册新用户或授权现有用户时的基本入口。95%的重定向案件在调用该方法时会发生。
客户端尚未确定将关联到哪个DC;因此,它会建立一个加密连接到一个随机地址,并将查询发送到该地址。 收到客户的phone_number后,我们可以查明该系统是否注册了。如果是,那么必要时,我们不发送短信,而是请求它先与另一个 DC 建立连接(PHONE_MIGRATE_X错误)。 如果我们还没有该号码的用户,我们会检查其IP地址。我们可以用它来识别最近的DC。同样,如有必要,我们会将用户重定向到另一个 DC(NETWORK_MIGRATE_X错误)。
测试重定向
有保留电话号码前缀用于测试应用程序处理 DC 间重定向的正确性。详情请参见用户授权文章。
文件访问
用户保存的带有 upload.saveFilePart 的文件,只能直接从查询执行的 DC 下载。这就是为什么每个文件都有一个dc_id参数:
document#8fd4c4d8 flags:# id:long access_hash:long file_reference:bytes date:int mime_type:string size:long thumbs:flags.0?Vector<PhotoSize> video_thumbs:flags.1?Vector<VideoSize> dc_id:int attributes:Vector<DocumentAttribute> = Document; photo#fb197a65 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> video_sizes:flags.1?Vector<VideoSize> dc_id:int = Photo; encryptedFile#a8008cd8 id:long access_hash:long size:long dc_id:int key_fingerprint:int = EncryptedFile; userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto; chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
要下载文件,必须建立与 DCdc_id的加密连接,并用于执行 upload.getFile 查询。 如果尝试通过错误连接下载文件,FILE_MIGRATE_X错误将返回。
请注意,加密密钥不会在数据中心之间复制;因此,建立加密连接的过程从每个新DC的头开始。通过授权转移,已签发的auth_key可以与当前授权用户关联。
用户迁移
在使用 API 的过程中,用户信息会被累积到用户所关联的 DC 中。这就是为什么用户不能通过客户端关联到不同的 DC。然而,将来在来自异常地点的长时间通信中,我们可能会决定必须将用户数据迁移到另一个数据中心。过一段时间后,数据会被复制,关联也会更新。一旦发生这种情况,执行任何向旧DC传输的查询时,API会返回USER_MIGRATE_X错误。客户端随后需要与新的 DC 建立连接并重复查询。
授权转移
以下方法可避免用户每次都从短信中输入代码:
auth.exportedAuthorization#b434e2b8 id:long bytes:bytes = auth.ExportedAuthorization; auth.authorization#2ea2c0d4 flags:# setup_password_required:flags.1?true otherwise_relogin_days:flags.1?int tmp_sessions:flags.0?int future_auth_token:flags.2?bytes user:User = auth.Authorization; ---functions--- auth.importAuthorization#a57a7dad id:long bytes:bytes = auth.Authorization; auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
auth.exportAuthorization 必须在当前 DC(已建立连接的 DC)中执行,dc_id作为新 DC 的值传递。该方法应返回用户标识符和一长串随机数据。导入操作可以在新 DC 执行,通过发送接收到的内容。需要授权的查询可以在新的 DC 中成功执行。