Интиқод аз протокол ва равишҳои ташкилии Telegram. Қисми 1, техникӣ: таҷрибаи навиштани муштарӣ аз сифр - TL, MT

Вақтҳои охир дар Habré мақолаҳо дар бораи то чӣ андоза хуб будани Telegram, то чӣ андоза олиҷаноб ва ботаҷриба будани бародарон Дуровҳо дар сохтани системаҳои шабакавӣ ва ғайра пайдо шуданд. Дар айни замон, хеле кам одамон воқеан худро ба дастгоҳи техникӣ ғарқ мекунанд - аксаран онҳо як API-и хеле содда (ва аз MTProto хеле фарқ мекунанд) дар асоси JSON Bot истифода мебаранд ва одатан танҳо қабул мекунанд. бар имон ҳамаи он ситоишҳо ва PR, ки дар атрофи паёмбар мечарханд. Тақрибан якуним сол пеш ҳамкори ман дар NPO Эшелон Василий (мутаассифона, аккаунти ӯ дар Хабре дар баробари лоиҳа нест карда шуд) аз сифр дар Perl навиштани муштарии Telegram-и худро оғоз кард ва баъдтар муаллифи ин сатрҳо ҳамроҳ шуд. Чаро Perl, баъзеҳо фавран мепурсанд? Чунки аллакай чунин лоиҳаҳо ба забонҳои дигар вуҷуд доранд.Аслан, гап дар ин нест, ягон забони дигаре вуҷуд дошта метавонад китобхонаи тамомшуда, ва мутаносибан муаллиф бояд тамоми роҳро тай кунад аз сифр. Гузашта аз ин, криптография чунин чизест - бовар кунед, аммо тафтиш кунед. Бо маҳсулоте, ки ба амният нигаронида шудааст, шумо наметавонед танҳо ба китобхонаи омодаи фурӯшанда такя кунед ва ба он кӯрона бовар кунед (аммо ин мавзӯъ барои бештар дар қисми дуюм аст). Дар айни замон, китобхона дар сатҳи "миёна" хеле хуб кор мекунад (ба шумо имкон медиҳад, ки ҳама гуна дархостҳои API-ро пешниҳод кунед).

Аммо, дар ин силсила мақолаҳо криптография ва математика зиёд нахоҳад буд. Аммо боз бисёр тафсилоти техникӣ ва асобаҳои меъморӣ (ин барои онҳое, ки аз сифр наменависанд, балки китобхонаро бо дилхоҳ забон истифода мебаранд) муфид хоҳад буд. Ҳамин тариқ, ҳадафи асосӣ кӯшиши амалӣ кардани муштарӣ аз сифр буд мувофиқи ҳуҷҷатҳои расмӣ. Яъне, фарз кунем, ки коди сарчашмаи муштариёни расмӣ баста аст (боз, дар қисми дуюм мо мавзӯъро муфассалтар ошкор хоҳем кард, ки ин воқеан чӣ аст. он рӯй медиҳад ҳамин тавр), аммо, ба монанди рӯзҳои қадим, масалан, стандарте ба монанди RFC вуҷуд дорад - оё метавон муштариро танҳо мувофиқи мушаххасот, "бе чашмгир" ба манбаъ, ҳатто расмӣ навишт (Telegram Desktop, мобилӣ) , ҳатто Telethon ғайрирасмӣ?

Мундариҷа:

Ҳуҷҷатҳо ... оё он ҷост? Дуруст аст?..

Порчаҳои ёддоштҳо барои ин мақола тобистони соли гузашта ҷамъоварӣ шуданд. Ҳамаи ин вақт дар сайти расмӣ https://core.telegram.org ҳуҷҷатҳо дар қабати 23 буд, яъне. дар ҷое дар соли 2014 часпида буд (дар хотир доред, ки он замон ҳатто каналҳо вуҷуд надоштанд?). Албатта, дар назария, ин бояд имкон медод, ки муштарии дорои функсия дар он вақт дар соли 2014 амалӣ карда шавад. Аммо дар ин долат хам хуччатхо, аввалан, нопурра буданд, сониян, дар чойхо хилофи худ ме-кард. Каме бештар аз як моҳ пеш, дар моҳи сентябри соли 2019, он буд тасодуфан маълум шуд, ки сайт дорои навсозии калони ҳуҷҷатҳо мебошад, барои қабати комилан тару тоза 105, бо қайд, ки ҳоло ҳама чизро дубора хондан лозим аст. Воқеан, мақолаҳои зиёде аз нав дида баромада шуданд, вале бисёре аз онҳо бетағйир монданд. Аз ин рӯ, ҳангоми хондани танқиди зер дар бораи ҳуҷҷатҳо, шумо бояд дар хотир дошта бошед, ки баъзе аз ин чизҳо дигар аҳамият надоранд, аммо баъзеҳо ҳоло ҳам комиланд. Баъд аз ҳама, 5 сол дар ҷаҳони муосир на танҳо бисёр, балки хеле бисёр. Аз он вақт инҷониб (махсусан агар шумо геочатҳои партофташуда ва эҳёшударо аз он вақт ба инобат нагиред), шумораи усулҳои API дар схема аз сад то дусаду панҷоҳ афзоиш ёфтааст!

Шумо ҳамчун нависандаи ҷавон аз куҷо оғоз мекунед?

Фарқ надорад, ки шумо аз сифр менависед ё истифода баред, масалан, китобхонаҳои тайёр ба монанди Telethon барои Python ё Madeline барои PHP, дар ҳар сурат, аввал ба шумо лозим меояд аризаи худро ба қайд гиред - параметрҳоро ба даст оред api_id и api_hash (онҳое, ки бо API VKontakte кор кардаанд, фавран мефаҳманд), ки тавассути он сервер барномаро муайян мекунад. Ин бояд ба бо сабабҳои ҳуқуқӣ, вале мо бештар дар бораи он сӯҳбат хоҳем кард, ки чаро муаллифони китобхона наметавонанд онро дар қисми дуюм нашр кунанд. Шояд шумо аз арзишҳои санҷиш қаноатманд бошед, гарчанде ки онҳо хеле маҳдуданд - далел ин аст, ки ҳоло шумо метавонед дар рақами худ сабти ном кунед танҳо якто ариза, бинобар ин саросема нашавед.

Ҳоло, аз нуқтаи назари техникӣ, мо бояд ба он таваҷҷӯҳ кунем, ки пас аз бақайдгирӣ мо бояд аз Telegram дар бораи навсозии ҳуҷҷатҳо, протокол ва ғайра огоҳинома гирем. Яъне тахмин кардан мумкин аст, ки сайти докҳо ба таври оддӣ "баҳо гирифта шудааст" ва махсусан бо онҳое, ки ба мизоҷон шурӯъ карданд, кор карданро идома медоданд, зеро. осонтар аст. Аммо не, чунин чизе мушохида нашуд, маълумоте наомад.

Ва агар шумо аз сифр нависед, пас истифодаи параметрҳои гирифташуда воқеан хеле дур аст. Гарчанде https://core.telegram.org/ ва дар бораи онҳо аввал дар Оғози кор сӯҳбат мекунад, дар асл, шумо аввал бояд амалӣ кунед Протоколи MTProto - аммо агар бовар кунед тарҳ аз рӯи модели OSI дар охири сахифаи тавсифи умумии протокол, баъд тамоман бехуда.

Дар асл, ҳам пеш аз MTProto ва ҳам баъд аз он, дар якчанд сатҳҳо якбора (чунон ки шабакаҳои хориҷӣ, ки дар ядрои OS кор мекунанд, вайронкунии қабат) як мавзӯи калон, дарднок ва даҳшатнок дар роҳ хоҳад шуд ...

Сериализатсияи дуӣ: TL (Type Language) ва схемаи он, қабатҳо ва бисёр калимаҳои даҳшатноки дигар

Дарвоқеъ ин мавзӯъ калиди мушкилоти Telegram аст. Ва агар шумо кӯшиш кунед, ки онро омӯзед, бисёр суханони даҳшатнок хоҳанд буд.

Пас, схема. Агар ин калимаро дар ёд дошта бошӣ, бигӯ: Схемаи JSONШумо дуруст фикр кардед. Мақсад як аст: баъзе забонҳо барои тавсифи маҷмӯи эҳтимолии додаҳои интиқолшуда. Дар асл, дар ин ҷо монандӣ ба охир мерасад. Агар аз сахифа Протоколи MTProto, ё аз дарахти сарчашмаи муштарии расмӣ, мо кӯшиш мекунем, ки ягон схемаро кушоем, мо чизеро мебинем:

int ? = Int;
long ? = Long;
double ? = Double;
string ? = String;

vector#1cb5c415 {t:Type} # [ t ] = Vector t;

rpc_error#2144ca19 error_code:int error_message:string = RpcError;

rpc_answer_unknown#5e2ad36e = RpcDropAnswer;
rpc_answer_dropped_running#cd78e586 = RpcDropAnswer;
rpc_answer_dropped#a43ad8b7 msg_id:long seq_no:int bytes:int = RpcDropAnswer;

msg_container#73f1f8dc messages:vector<%Message> = MessageContainer;

---functions---

set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:bytes = Set_client_DH_params_answer;

ping#7abe77ec ping_id:long = Pong;
ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;

invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X;

account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
account.sendChangePhoneCode#8e57deb flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;

Шахсе, ки инро бори аввал мебинад, ба таври интуитивӣ танҳо як қисми он чизе, ки навишта шудааст, эътироф мекунад - хуб, инҳо аз афташ сохторҳо ҳастанд (гарчанде ки ном дар куҷост, дар чап ё рост?), Дар онҳо майдонҳо мавҷуданд, ки пас аз он. навъи ба воситаи ғафс мегузарад ... эҳтимол. Дар ин ҷо, дар қавсҳои кунҷӣ, эҳтимол қолабҳое ҳастанд, ки дар C ++ (дар асл, на он қадар). Ва ҳамаи рамзҳои дигар чӣ маъно доранд, аломатҳои савол, аломатҳои нидо, фоизҳо, торҳо (ва бешубҳа онҳо дар ҷойҳои гуногун чизҳои гуногунро доранд), дар ҷое мавҷуданд, аммо на дар ҷое, рақамҳои шонздаҳӣ - ва муҳимтар аз ҳама, аз ин чӣ гуна ба даст овардан мумкин аст дуруст (ки аз ҷониби сервер рад карда намешавад) ҷараёни байт? Шумо бояд ҳуҷҷатҳоро хонед (Бале, дар наздикии версияи JSON ба схема истинодҳо мавҷуданд - аммо ин онро равшантар намекунад).

Кушодани саҳифа Сериализатсияи маълумотҳои дуӣ ва ба олами ҷодугарии занбурўғҳо ва математикаи дискретӣ, чизе монанд ба матан дар соли 4 ғарқ шавед. Алифбо, намуд, арзиш, комбинатор, комбинатори функсионалӣ, шакли муқаррарӣ, навъи таркибӣ, навъи полиморфӣ... ва ин танҳо саҳифаи аввал аст! Оянда шуморо интизор аст Забони TL, ки гарчанде ки он аллакай як мисоли дархост ва посухи ночизро дар бар мегирад, аммо ба ҳолатҳои маъмулӣ умуман ҷавоб намедиҳад, ки ин маънои онро дорад, ки шумо бояд дар ҳашт лонаҳои дигар аз такрори математикаи аз русӣ ба англисӣ тарҷумашуда гузаред. саҳифаҳо!

Хонандагоне, ки бо забонҳои функсионалӣ ва хулосабарории навъи автоматӣ ошно ҳастанд, албатта, дар ин забон тавсифи ҳатто аз як мисол хеле ошнотар диданд ва гуфта метавонанд, ки ин умуман дар асл бад нест. Эътирозҳо ба ин инҳоянд:

  • ҳа, цель хуб садо медиҳад, аммо афсӯс ба даст наомадааст
  • таҳсил дар донишгоҳҳои Русия ҳатто дар байни ихтисосҳои IT фарқ мекунад - на ҳама курси мувофиқро мехонанд
  • Дар охир, чунон ки мебинем, дар амал чунин аст талаб карда намешавад, зеро танҳо як қисми маҳдуди ҳатто TL, ки тавсиф шудааст, истифода мешавад

Чунон ки гуфтем ЛеоНерд дар канал #perl дар шабакаи FreeNode IRC, кӯшиши амалӣ кардани дарвоза аз Telegram ба Matrix (тарҷумаи иқтибос аз хотира нодуруст аст):

Чунин ба назар мерасад, ки касе, ки бори аввал бо назарияи чопӣ шинос шуда буд, ба ҳаяҷон омад ва кӯшиш кард, ки бо он бозӣ кунад, аслан парвое надорад, ки оё он дар амал зарур буд.

Худатон бубинед, ки оё эҳтиёҷ ба навъҳои бараҳна (int, long ва ғайра) ҳамчун чизи ибтидоӣ саволҳоро ба миён намеорад - дар ниҳоят онҳо бояд дастӣ амалӣ карда шаванд - масалан, биёед кӯшиш кунем, ки аз онҳо ҳосил кунем. вектор. Яъне, дар асл, массиви, агар шумо чизҳои ҳосилшударо бо номҳои хосашон хонед.

Аммо пештар

Тавсифи мухтасари зермаҷмӯи синтаксиси TL барои онҳое, ки намедонанд… ҳуҷҷатҳои расмиро хонед

constructor = Type;
myVec ids:Vector<long> = Type;

fixed#abcdef34 id:int = Type2;

fixedVec set:Vector<Type2> = FixedVec;

constructorOne#crc32 field1:int = PolymorType;
constructorTwo#2crc32 field_a:long field_b:Type3 field_c:int = PolymorType;
constructorThree#deadcrc bit_flags_of_what_really_present:# optional_field4:bit_flags_of_what_really_present.1?Type = PolymorType;

an_id#12abcd34 id:int = Type3;
a_null#6789cdef = Type3;

Ҳамеша таърифро оғоз мекунад созанда, баъд аз он, ихтиёрӣ (дар амал, ҳамеша) тавассути аломат # бояд CRC32 аз сатри тавсифи нормалшудаи навъи додашуда. Баъдан тавсифи майдонҳо меояд, агар онҳо бошанд - навъи метавонад холӣ бошад. Њамаи он бо аломати баробар ба охир мерасад, номи намуде, ки конструктори додашуда ба он тааллуќ дорад, яъне дар воќеъ, зертип. Навъи дар тарафи рости аломати баробар аст полиморфӣ - яъне он метавонад ба якчанд намуди мушаххас мувофиқат кунад.

Агар таъриф пас аз сатр пайдо шавад ---functions---, он гоҳ синтаксис бетағйир мемонад, аммо маъно дигар хоҳад буд: созанда номи функсияи RPC мегардад, майдонҳо ба параметрҳо табдил меёбанд (хуб, яъне он ҳамон сохтори додашуда боқӣ мемонад, ки дар зер тавсиф шудааст, он танҳо маънои додашуда хоҳад буд) ва "навъи полиморфӣ" навъи натиҷаи баргардонидашуда мебошад. Дуруст аст, ки он ҳанӯз ҳам полиморфӣ боқӣ мемонад - танҳо дар бахш муайян карда шудааст ---types---, ва ин конструктор ба назар гирифта намешавад. Аз рӯи аргументҳояшон изофабории функсияҳои даъватшударо нависед, яъне. бо баъзе сабабҳо, дар TL якчанд функсияҳо бо як ном, вале имзои дигар, ба монанди C++, таъмин карда намешаванд.

Чаро "конструктор" ва "полиморфӣ" агар он OOP набошад? Хуб, дар асл, барои касе осонтар мешавад, ки дар ин бора аз нуқтаи назари OOP фикр кунад - як навъи полиморфӣ ҳамчун синфи абстрактӣ ва конструкторҳо синфҳои насли мустақими он мебошанд, илова бар ин final дар истилохоти як катор забонхо. Дар асл, албатта, дар ин ҷо монандӣ бо усулҳои воқеии созанда дар забонҳои барномасозии OO. Азбаски дар ин ҷо танҳо сохторҳои додаҳо мавҷуданд, усулҳо вуҷуд надоранд (гарчанде ки тавсифи функсияҳо ва усулҳои дар поён овардашуда қодир аст, ки дар сар дар бораи он ки онҳо чӣ гунаанд, нофаҳмиҳо эҷод кунанд, аммо ин дар бораи чизи дигар аст) - шумо метавонед конструкторро ҳамчун арзиш аз он сохта шуда истодааст ҳангоми хондани ҷараёни байтҳо нависед.

Ин чӣ гуна рӯй медиҳад? Deserializer, ки ҳамеша 4 байтро мехонад, арзишро мебинад 0xcrc32 - ва мефаҳмад, ки минбаъд чӣ мешавад field1 бо навъи int, яъне. маҳз 4 байт мехонад, дар ин майдони болои бо навъи PolymorType хонед. Мебинад 0x2crc32 ва мефаҳмад, ки ду соҳаи минбаъда вуҷуд дорад, аввал long, бинобар ин мо 8 байтро мехонем. Ва он гоҳ боз як намуди мураккаб, ки ба ҳамин тарз deserialized аст. Барои намуна, Type3 метавонад дар схема эълон карда шавад, вақте ки мутаносибан ду конструктор, минбаъд бояд бо ҳам вохӯранд 0x12abcd34, пас аз он шумо бояд 4 байти дигарро хонед int, ё 0x6789cdef, ки пас аз он чизе нахоҳад буд. Ҳама чизи дигар - шумо бояд истисноро партоед. Ба ҳар ҳол, пас аз ин мо ба мутолиаи 4 байт бармегардем int майдонҳо field_c в constructorTwo ва дар ин бора мо хондани худро ба охир мерасонем PolymorType.

Ниҳоят, агар дастгир 0xdeadcrc барои constructorThree, пас кор боз мураккабтар мешавад. Майдони аввалини мо bit_flags_of_what_really_present бо навъи # - дар асл, ин танҳо тахаллус барои навъи аст natмаънои «шумораи табиӣ». Яъне, дар асл, unsigned int ягона ҳолатест, ки рақамҳои беимзо дар схемаҳои воқеӣ пайдо мешаванд. Ҳамин тавр, навбатӣ конструксия бо аломати савол аст, ки маънои онро дорад, ки ин майдон аст - он танҳо дар сим мавҷуд хоҳад буд, агар битаи мувофиқ дар майдони истинодшуда (тақрибан ба монанди оператори сегона) насб карда шавад. Пас, фарз кунед, ки ин бит фаъол буд, пас шумо бояд як майдонеро хонед Type, ки дар мисоли мо 2 конструктор дорад. Яке холӣ аст (танҳо аз муайянкунанда иборат аст), дигаре майдон дорад ids бо навъи ids:Vector<long>.

Шумо шояд фикр кунед, ки ҳам шаблонҳо ва ҳам генерикҳо хуб ё Java мебошанд. Аммо не. Қариб. Ин ягона ҳолати қавсҳои кунҷӣ дар схемаҳои воқеӣ ва он ТАНҲО барои Вектор истифода мешавад. Дар ҷараёни байт, ин барои худи навъи Вектор 4 CRC32 байт хоҳад буд, ҳамеша якхела, баъд 4 байт - шумораи элементҳои массив ва сипас худи ин элементҳо.

Ба ин илова кунед, ки сериализатсия ҳамеша бо калимаҳои 4 байт рух медиҳад, ҳама намудҳо ба он баробар мебошанд - навъҳои дарунсохт низ тавсиф карда мешаванд. bytes и string бо serialization дастӣ дарозии ва ин ҳамоҳангӣ аз тарафи 4 - хуб, ба назар мерасад, он муқаррарӣ ва ҳатто нисбатан самаранок садо? Гарчанде ки TL иддао мешавад, ки сериализатсияи самарабахши дуӣ аст, аммо ба ҷаҳаннам бо тавсеаи ҳама чиз, ҳатто арзишҳои булӣ ва сатрҳои як аломати то 4 байт, оё JSON боз ҳам ғафстар хоҳад буд? Нигоҳ кунед, ҳатто майдонҳои нолозимро бо парчамҳои бит гузариш кардан мумкин аст, ҳама чиз хуб аст ва ҳатто барои оянда васеъ карда мешавад, оё шумо баъдтар ба конструктор майдонҳои нави ихтиёриро илова кардаед?..

Аммо не, агар шумо на тавсифи мухтасари ман, балки ҳуҷҷатҳои пурраро хонед ва дар бораи татбиқи он фикр кунед. Аввалан, CRC32-и созанда аз рӯи сатри тавсифи матни схемаи муқарраршуда ҳисоб карда мешавад (хосагии изофӣ хориҷ кунед ва ғ.) - аз ин рӯ, агар майдони нав илова карда шавад, сатри тавсифи навъи он тағир меёбад ва аз ин рӯ, CRC32 ва дар натиҷа сериализатсия мешавад. Ва муштарии кӯҳна чӣ кор мекард, агар ӯ майдонеро бо парчамҳои нав гирифта бошад, аммо намедонист, ки минбаъд бо онҳо чӣ кор кунад? ..

Дуюм, биёед дар хотир дорем CRC32, ки дар ин ҷо асосан ҳамчун истифода бурда мешавад вазифаҳои шудаи барои ба таври ягона муайян кардани кадом навъи сериализатсия (де) карда мешавад. Дар ин ҷо мо бо мушкилоти бархӯрд рӯ ба рӯ мешавем - ва не, эҳтимолият дар як 232 нест, балки хеле бештар аст. Кӣ дар хотир дошт, ки CRC32 барои ошкор (ва ислоҳ кардани) хатогиҳо дар канали коммуникатсия ва мувофиқан беҳтар кардани ин хосиятҳо ба зарари дигарон пешбинӣ шудааст? Масалан, вай ба ивазкунии байтҳо аҳамият надорад: агар шумо CRC32-ро аз ду сатр ҳисоб кунед, дар дуюм шумо 4 байти аввалро бо 4 байти оянда иваз мекунед - ин ҳамон хоҳад буд. Вақте ки мо сатрҳои матниро аз алифбои лотинӣ (ва аломати каме) ҳамчун вуруд дорем ва ин номҳо махсусан тасодуфӣ нестанд, эҳтимолияти чунин ивазшавӣ хеле зиёд мешавад.

Дар омади гап, кй тафтиш кард, ки дар он чо чй буд дар ҳақиқат CRC32? Дар яке аз сарчашмаҳои ибтидоӣ (ҳатто пеш аз Уолтман) функсияи хэш мавҷуд буд, ки ҳар як аломатро ба рақами 239 зарб мекард, ки аз ҷониби ин одамон маҳбуб аст, ҳа ҳа!

Ниҳоят, хуб, мо фаҳмидем, ки конструкторҳо бо навъи майдон Vector<int> и Vector<PolymorType> CRC32-и гуногун хоҳад дошт. Ва дар бораи презентатсия дар сатр чӣ гуфтан мумкин аст? Ва аз ҷиҳати назария, оё он як қисми намуд мешавад? Биё мегӯянд, ки мо як массиви даҳ ҳазор рақамҳо мегузарад, хуб, бо Vector<int> ҳама чиз равшан аст, дарозӣ ва дигар 40000 байт. Ва агар ин Vector<Type2>, ки танхо аз як майдон иборат аст int ва он ягона дар намуд аст - оё мо бояд 10000xabcdef0-ро 34 маротиба ва сипас 4 байт такрор кунем int, ё забон қодир аст, ки инро барои мо аз созанда НАМОИШ диҳад fixedVec ва ба ҷои 80000 40000 байт боз ҳамагӣ XNUMX XNUMX интиқол диҳед?

Ин умуман як саволи назариявии холӣ нест - тасаввур кунед, ки шумо рӯйхати корбарони гурӯҳро мегиред, ки ҳар яки онҳо ID, ном ва насаб доранд - фарқият дар ҳаҷми маълумоте, ки тавассути пайвасти мобилӣ интиқол дода мешавад, метавонад назаррас бошад. Маҳз самаранокии сериализатсияи Telegram ба мо эълон карда мешавад.

Ҳамин тавр ...

Векторе, ки онро баровардан мумкин нест

Агар шумо кӯшиш кунед, ки аз саҳифаҳои тавсифи комбинаторҳо ва атрофи он гузаред, шумо хоҳед дид, ки вектор (ва ҳатто матритса) ба таври расмӣ кӯшиш мекунад, ки якчанд варақҳоро тавассути наворҳо ба даст орад. Аммо дар ниҳоят онҳо гурзандозӣ мешаванд, қадами ниҳоӣ гузаронида мешавад ва таърифи вектор ба таври оддӣ дода мешавад, ки он низ ба намуд вобаста нест. Ин ҷо чӣ гап? Ба забонхо барномасозӣ, махсусан функсионалӣ, ба таври рекурсивӣ тавсиф кардани сохтор хеле маъмул аст - компилятор бо арзёбии танбали худ ҳама чизро мефаҳмад ва онро иҷро мекунад. Ба забон силсилаи маълумот балки САМАРАНОКЙ лозим аст: фадат тавсиф кардан кифоя аст рӯйхат, яъне. сохтори ду элемент - якум унсури маълумот, дуюм худи ҳамон сохтор ё фазои холӣ барои дум (маҷмӯа) (cons) дар Лисп). Аммо ин бешубха талаб мекунад ҳар яке элемент барои тавсифи навъи худ ба таври илова 4 байт (CRC32 дар мавриди TL) сарф мекунад. Массивро тавсиф кардан осон аст андозаи муқарраршуда, аммо дар сурати массиви дарозии қаблан номаълум, мо ҷудо мешавем.

Ҳамин тавр, азбаски TL ба шумо имкон намедиҳад, ки векторро бароваред, он бояд дар паҳлӯ илова карда шавад. Дар ниҳоят, ҳуҷҷатҳо мегӯяд:

Сериализатсия ҳамеша як созандаи "вектор"-ро истифода мебарад (const 0x1cb5c415 = crc32("вектор t:Намуд # [ t ] = Vector t"), ки аз арзиши мушаххаси тағирёбандаи навъи t вобаста нест.

Қимати параметри ихтиёрии t дар сериализатсия иштирок намекунад, зеро он аз навъи натиҷа гирифта шудааст (ҳамеша қабл аз бесериализатсия маълум аст).

Бодиққат назар кунед: vector {t:Type} # [ t ] = Vector t - аммо ҳеҷ чиз нест худи таъриф намегӯяд, ки рақами аввал бояд ба дарозии вектор баробар бошад! Ва он аз ҳеҷ куҷо пайравӣ намекунад. Ин додаест, ки шумо бояд онро дар хотир нигоҳ доред ва бо дасти худ амалӣ кунед. Дар ҷои дигар, ҳуҷҷатҳо ҳатто ростқавлона қайд мекунанд, ки ин навъи қалбакӣ аст:

Псевдотипи полиморфии Vector t як "намуд" аст, ки арзиши он пайдарпайии арзишҳои ҳама гуна намуди t мебошад, ё қуттиҳо ё бараҳна.

... аммо ба он таваҷҷӯҳ намекунад. Ҳангоме ки шумо аз гузаштан аз омӯзиши математика (шояд ҳатто аз курси донишгоҳ маълум бошад) хаста шудаед, тасмим гирифтед, ки баҳо гузоред ва бубинед, ки чӣ тавр дар амал бо он кор кардан лозим аст, таассурот дар сари шумо боқӣ мемонад: дар ин ҷо Математикаи Ҷиддӣ ба он асос ёфтааст. , баръало Одамони сард (ду математик - ғолиби ACM), на танҳо касе. Максад — харч кардан — ба даст омад.

Воқеан, дар бораи рақам. Ба ёд оред # синоним аст nat, рақами табиӣ:

Ифодаҳои навъи вуҷуд доранд (typeexpr) ва ифодаҳои ададӣ (nat-expr). Бо вуҷуди ин, онҳо ҳамон тавр муайян карда мешаванд.

type-expr ::= expr
nat-expr ::= expr

вале дар грамматика як хел тасвир карда шудаанд, яъне. ин тафовутро боз ба хотир оварда, дастй ба амал баровардан лозим аст.

Хуб, бале, намудҳои шаблон (vector<int>, vector<User>) муайянкунандаи умумӣ (#1cb5c415), яъне. агар шумо медонед, ки занг ҳамчун эълон карда мешавад

users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;

пас шумо интизори на танҳо вектор, балки вектори истифодабарандагон ҳастед. Аниқтараш, бояд мунтазир бошед - дар коди воқеӣ, ҳар як элемент, агар як навъи луч набошад, конструктор дорад ва ба таври хуб ҳангоми татбиқ тафтиш кардан лозим буд - ва мо маҳз дар ҳар як элементи ин вектор фиристода шудаем. он навъи? Ва агар он як намуди PHP бошад, ки дар он массив метавонад намудҳои гуногунро дар унсурҳои гуногун дошта бошад?

Дар ин лаҳза, шумо ҳайрон мешавед - оё чунин TL лозим аст? Шояд барои ароба мумкин аст, ки сериализатори инсониро истифода барад, ҳамон протобуф, ки он вақт вуҷуд дошт? Ин назария буд, биёед ба амалия назар кунем.

Амалиётҳои мавҷудаи TL дар код

TL дар дохили ВКонтакте ҳатто пеш аз рӯйдодҳои маъруф бо фурӯши саҳмияи Дуров таваллуд шудааст ва (Албатта), ҳатто пеш аз таҳияи Telegram. Ва дар манбаи кушода манбаъхои татбики аввалин шумо метавонед бисёр асобагон хандовар ёфт. Ва худи забон дар онҷо пурратар аз ҳоло дар Telegram амалӣ карда шуд. Масалан, хэшҳо дар схема умуман истифода намешаванд (дар назар аст, ки псевдотипи дарунсохт (ба мисли вектор) бо рафтори девианти). Ё

Templates are not used now. Instead, the same universal constructors (for example, vector {t:Type} [t] = Vector t) are used w

балки барои пурра шудан манзараро ба назар гирем, то ки, ба ибораи дигар, эволютсияи азимҷуссаи андешаро пайгирӣ кунем.

#define ZHUKOV_BYTES_HACK

#ifdef ZHUKOV_BYTES_HACK

/* dirty hack for Zhukov request */

Ё ин зебои:

    static const char *reserved_words_polymorhic[] = {

      "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", NULL

      };

Ин порча дар бораи қолибҳо аст, ба монанди:

intHash {alpha:Type} vector<coupleInt<alpha>> = IntHash<alpha>;

Ин таърифи навъи шаблони hasshmap аст, ҳамчун вектори ҷуфтҳои int - Type. Дар C++ он чизе монанди ин хоҳад буд:

    template <T> class IntHash {
      vector<pair<int,T>> _map;
    }

ҳамин тавр, alpha - калимаи калид! Аммо танҳо дар C++ шумо метавонед T нависед, аммо шумо бояд алфа, бета нависед... Аммо на бештар аз 8 параметр, фантазия дар тета анҷом ёфт. Пас, ба назар чунин мерасад, ки боре дар Санкт-Петербург тақрибан чунин муколамаҳо буданд:

-- Надо сделать в TL шаблоны
-- Бл... Ну пусть параметры зовут альфа, бета,... Какие там ещё буквы есть... О, тэта!
-- Грамматика? Ну потом напишем

-- Смотрите, какой я синтаксис придумал для шаблонов и вектора!
-- Ты долбанулся, как мы это парсить будем?
-- Да не ссыте, он там один в схеме, захаркодить -- и ок

Аммо сухан дар бораи татбиқи аввалини ХИБ "умуман" буд. Биёед ба баррасии татбиқ дар муштариёни воқеии Telegram гузарем.

Каломи Базил:

Василий, [09.10.18 17:07] Бештар аз ҳама, хар аз он гарм аст, ки онҳо як даста абстраксияҳоро печонданд ва сипас ба болт заданд ва кодгегераторро бо асобағалҳо пӯшониданд.
Дар натича аввал аз докхо пилот.jpg
Сипас аз рамзи jekichan.webp

Албатта, аз одамоне, ки бо алгоритмҳо ва математика ошно ҳастанд, мо метавонем интизор шавем, ки онҳо Aho, Ullman-ро хондаанд ва бо асбобҳое шиносанд, ки дар тӯли даҳсолаҳо барои навиштани компиляторҳои DSL-и худ стандарти воқеии саноат гаштаанд, дуруст? . .

Бо телеграмма-кли Виталий Валтман аст, чунон ки аз пайдоиши формати TLO берун аз ҳудуди он (cli) фаҳмида мешавад, узви даста - ҳоло китобхона барои таҳлили TL ҷудо карда шудааст. алоҳидатаассуроти вай чй гуна аст Таҳлилгари TL? ..

16.12 04:18 Василий: ба назари ман, касе lex + yacc -ро азхуд накардааст
16.12 04:18 Василий: вагарна ман инро шарҳ дода наметавонам
16.12 04:18 Василий: хуб, ё онҳо барои шумораи сатрҳо дар ВК пул гирифтаанд
16.12 04:19 Василий: 3k+ сатри дигарон<censored> ба ҷои таҳлилгар

Шояд истисно? Биёед бубинем, ки чӣ тавр мекунад ин муштарии РАСМИИ аст — Мизи кории Telegram:

    nametype = re.match(r'([a-zA-Z.0-9_]+)(#[0-9a-f]+)?([^=]*)=s*([a-zA-Z.<>0-9_]+);', line);
    if (not nametype):
      if (not re.match(r'vector#1cb5c415 {t:Type} # [ t ] = Vector t;', line)):
         print('Bad line found: ' + line);

1100+ сатр дар Python, якчанд ибораҳои муқаррарӣ + ҳолатҳои махсуси навъи вектор, ки албатта дар схема эълон карда шудааст, тавре ки он бояд мувофиқи синтаксиси TL бошад, аммо онҳо онро ба ин синтаксис гузоштаанд, бештар таҳлил мекунанд. ...Саволе ба миён меояд, ки чаро бо ин ҳама муъҷиза ранҷ мекашед?изиёдтар, агар ҳеҷ кас онро мувофиқи ҳуҷҷатҳо таҳлил накунад ?!

Дар омади гап... Дар хотир доред, ки мо дар бораи чеки CRC32 гап зада будем? Ҳамин тавр, дар генератори рамзи Telegram Desktop рӯйхати истисноҳо барои он намудҳое мавҷуд аст, ки дар онҳо CRC32 ҳисоб карда мешавад. мувофиқат намекунад чунон ки дар диаграмма нишон дода шудааст!

Василий, [18.12 22:49] ва дар ин ҷо шумо бояд дар бораи он фикр кунед, ки оё чунин TL лозим аст ё не
агар ман мехостам бо татбиқи алтернативӣ халалдор шавам, ман ба ворид кардани танаффусҳои сатр шурӯъ мекардам, нисфи таҳлилгарон дар таърифҳои бисёрсатрӣ мешикананд
tdesktop, аммо

Нуктаро дар бораи як-лайнерхо дар хотир доред, каме дертар ба он бармегардем.

Хуб, telegram-cli ғайрирасмӣ аст, Telegram Desktop расмӣ аст, аммо дигарон чӣ? Ва кӣ медонад?.. Дар коди муштарии Android, умуман таҳлилгари схема вуҷуд надошт (ки саволҳоро дар бораи манбаи кушода ба миён меорад, аммо ин барои қисми дуюм аст), аммо якчанд қисмҳои дигари кодҳо мавҷуданд, аммо дар бораи онҳо дар зербахши дар поён.

Сериализатсия дар амал боз кадом саволҳоро ба миён меорад? Масалан, онҳо, албатта, бо майдонҳои бит ва майдонҳои шартӣ печида буданд:

Василий: flags.0? true
маънои онро дорад, ки майдон мавҷуд аст ва дуруст аст, агар парчам гузошта шуда бошад

Василий: flags.1? int
маънои онро дорад, ки майдон мавҷуд аст ва бояд сериализатсия карда шавад

Василий: Хар, сухта нашав, ту чӣ кор мекунӣ!
Василий: Дар ҷое дар ҳуҷҷат зикр шудааст, ки true як навъи бараҳнаи дарозии сифр аст, аммо ҷамъоварӣ кардани чизе аз ҳуҷҷатҳои онҳо ғайривоқеӣ аст
Василий: Дар татбиқи кушод низ чунин чизе вуҷуд надорад, аммо асобагон ва реквизитҳо зиёданд

Дар бораи телефон чӣ гуфтан мумкин аст? Ба пеш дар мавзӯи MTProto, як мисол - дар ҳуҷҷатҳо чунин қисмҳо мавҷуданд, аммо аломат % он танҳо ҳамчун "мувофиқ ба луч-намуди додашуда" тавсиф карда мешавад, яъне. дар мисолҳои дар поён овардашуда, ё хато, ё чизи ҳуҷҷатнашуда:

Василий, [22.06.18 18:38] Дар як ҷо:

msg_container#73f1f8dc messages:vector message = MessageContainer;

Дар дигар:

msg_container#73f1f8dc messages:vector<%Message> = MessageContainer;

Ва ин ду фарқияти калон аст, дар ҳаёти воқеӣ як навъ вектори бараҳна меояд

Ман таърифҳои вектории лучро надидам ва ба он дучор нашудаам

Таҳлил бо дастӣ дар телефон навишта шудааст

Схемаи ӯ таърифро шарҳ дод msg_container

Боз савол дар бораи% боқӣ мемонад. Он тавсиф карда нашудааст.

Вадим Гончаров, [22.06.18 19:22] ва дар мизи корӣ?

Василий, [22.06.18/19/23 XNUMX:XNUMX] Аммо таҳлилгари TL-и онҳо дар танзимгарон эҳтимолан онро ҳам нахӯрад

// parsed manually

TL абстраксияи зебост, касе онро пурра амалӣ намекунад

Ва дар версияи схемаи онҳо % вуҷуд надорад

Аммо дар ин ҷо ҳуҷҷатҳо ба худ мухолифанд, бинобар ин xs

Он дар грамматика пайдо шуд, онҳо метавонистанд тавсифи семантикаро фаромӯш кунанд

Хуб, шумо докро дар TL дидед, онро бе ним литр фаҳмида наметавонед

"Хуб, биёед бигӯем," хонандаи дигар мегӯяд, "шумо ҳама чизро танқид мекунед, пас онро тавре нишон диҳед, ки лозим аст."

Василий чавоб медихад: «Дар бораи тахлилкунанда бошад, ба ман чунин чизхо лозиманд

    args: /* empty */ { $$ = NULL; }
        | args arg { $$ = g_list_append( $1, $2 ); }
        ;

    arg: LC_ID ':' type-term { $$ = tl_arg_new( $1, $3 ); }
            | LC_ID ':' condition '?' type-term { $$ = tl_arg_new_cond( $1, $5, $3 ); free($3); }
            | UC_ID ':' type-term { $$ = tl_arg_new( $1, $3 ); }
            | type-term { $$ = tl_arg_new( "", $1 ); }
            | '[' LC_ID ']' { $$ = tl_arg_new_mult( "", tl_type_new( $2, TYPE_MOD_NONE ) ); }
            ;

гӯё бештар аз

struct tree *parse_args4 (void) {
  PARSE_INIT (type_args4);
  struct parse so = save_parse ();
  PARSE_TRY (parse_optional_arg_def);
  if (S) {
    tree_add_child (T, S);
  } else {
    load_parse (so);
  }
  if (LEX_CHAR ('!')) {
    PARSE_ADD (type_exclam);
    EXPECT ("!");
  }
  PARSE_TRY_PES (parse_type_term);
  PARSE_OK;
}

ё

        # Regex to match the whole line
        match = re.match(r'''
            ^                  # We want to match from the beginning to the end
            ([w.]+)           # The .tl object can contain alpha_name or namespace.alpha_name
            (?:
                #             # After the name, comes the ID of the object
                ([0-9a-f]+)    # The constructor ID is in hexadecimal form
            )?                 # If no constructor ID was given, CRC32 the 'tl' to determine it

            (?:s              # After that, we want to match its arguments (name:type)
                {?             # For handling the start of the '{X:Type}' case
                w+            # The argument name will always be an alpha-only name
                :              # Then comes the separator between name:type
                [wd<>#.?!]+  # The type is slightly more complex, since it's alphanumeric and it can
                               # also have Vector<type>, flags:# and flags.0?default, plus :!X as type
                }?             # For handling the end of the '{X:Type}' case
            )*                 # Match 0 or more arguments
            s                 # Leave a space between the arguments and the equal
            =
            s                 # Leave another space between the equal and the result
            ([wd<>#.?]+)     # The result can again be as complex as any argument type
            ;$                 # Finally, the line should always end with ;
            ''', tl, re.IGNORECASE | re.VERBOSE)

ин ТАМОМИ луғат:

    ---functions---         return FUNCTIONS;
    ---types---             return TYPES;
    [a-z][a-zA-Z0-9_]*      yylval.string = strdup(yytext); return LC_ID;
    [A-Z][a-zA-Z0-9_]*      yylval.string = strdup(yytext); return UC_ID;
    [0-9]+                  yylval.number = atoi(yytext); return NUM;
    #[0-9a-fA-F]{1,8}       yylval.number = strtol(yytext+1, NULL, 16); return ID_HASH;

    n                      /* skip new line */
    [ t]+                  /* skip spaces */
    //.*$                 /* skip comments */
    /*.**/              /* skip comments */
    .                       return (int)yytext[0];

ки. соддатар он аст, ки онро нарм баён кунед."

Умуман, дар ниҳоят, таҳлилгар ва генератори код барои зермаҷмӯаи воқеан истифодашудаи TL ба тақрибан 100 сатри грамматика ва ~ 300 сатри генератор (аз ҷумла ҳама) мувофиқат мекунанд. printкоди тавлидшуда), аз ҷумла навъи хушҳолӣ, маълумотро барои интроспекция дар ҳар як синф нависед. Ҳар як намуди полиморфӣ ба синфи абстрактии холӣ табдил дода мешавад ва конструкторҳо аз он мерос мегиранд ва дорои усулҳои сериализатсия ва десериализатсия мебошанд.

Набудани намудҳо дар забони тип

Навиштани қавӣ хуб аст, дуруст? Не, ин холивар нест (гарчанде ки ман забонҳои динамикиро афзалтар мешуморам), балки постулат дар дохили TL. Дар асоси он забон бояд ҳама гуна чекҳоро барои мо таъмин кунад. Хуб, хуб, бигзор вай на, балки татбиқ, вале ӯ бояд ҳадди аққал онҳоро тавсиф кунад. Ва мо чӣ гуна имкониятҳоро мехоҳем?

Пеш аз ҳама, маҳдудиятҳо. Дар ин ҷо мо дар ҳуҷҷатҳо барои боркунии файлҳо мебинем:

Пас аз он мундариҷаи дуии файл ба қисмҳо тақсим карда мешавад. Ҳама қисмҳо бояд андозаи якхела дошта бошанд ( қисм_андоза ) ва шартҳои зерин бояд риоя шаванд:

  • part_size % 1024 = 0 (ба 1КБ тақсим мешавад)
  • 524288 % part_size = 0 (512KB бояд аз рӯи қисм_андоза баробар тақсим карда шавад)

Қисми охирин набояд ин шартҳоро қонеъ кунад, ба шарте ки андозаи он аз part_size камтар бошад.

Ҳар як қисм бояд рақами пайдарпай дошта бошад, файл_қисми, бо қимати аз 0 то 2,999.

Пас аз тақсим кардани файл шумо бояд усули захира кардани онро дар сервер интихоб кунед. истифода бурдан upload.saveBigFilePart дар сурати зиёда аз 10 МБ андозаи пурраи файл ва upload.saveFilePart барои файлҳои хурдтар.
[…] яке аз хатогиҳои зерини вуруди маълумот метавонад баргардонида шавад:

  • FILE_PARTS_INVALID - Шумораи қисмҳои нодуруст. Арзиш дар байни 1..3000

Оё яке аз инҳо дар схема мавҷуд аст? Оё онро тавассути TL ифода кардан мумкин аст? Не. Аммо бубахшед, зеро ҳатто Турбо Паскал кӯҳна тавонист намудҳоеро, ки аз ҷониби диапазонҳо. Ва ӯ метавонист боз як чизи дигарро иҷро кунад, ки ҳоло онро беҳтар медонанд enum - навъе, ки аз номбаркунии шумораи собит (хурд) арзишҳо иборат аст. Дар забонҳои монанди C - рақамӣ, дар хотир доред, ки мо то ҳол танҳо дар бораи намудҳо сӯҳбат кардем. рақамҳо. Аммо инчунин массивҳо, сатрҳо мавҷуданд ... масалан, хуб мебуд, ки тавсиф кунем, ки ин сатр танҳо рақами телефонро дар бар гирад, дуруст?

Ҳеҷ яке аз инҳо дар TL нест. Аммо, масалан, дар JSON Schema вуҷуд дорад. Ва агар ягон каси дигар метавонад дар бораи тақсимшавандагии 512 KB эътироз кунад, ки ин ҳоло ҳам бояд дар код тафтиш карда шавад, пас боварӣ ҳосил кунед, ки муштарӣ оддӣ аст. натавонист рақамро аз доираи диапазон фиристед 1..3000 (ва хатогии мувофиқ ба вуҷуд омада наметавонист) ин имконпазир мебуд, дуруст? ..

Дар омади гап, дар бораи хатогиҳо ва арзишҳои бозгашт. Чашм ҳатто барои онҳое, ки бо TL кор кардаанд, норавшан аст - ин дарҳол ба мо нарасид ҳар як Функсия дар TL метавонад воқеан на танҳо намуди бозгашти тавсифшуда, балки хаторо низ баргардонад. Аммо ин тавассути худи TL муайян карда намешавад. Албатта, ин фаҳмо аст ва нафиғ дар амал лозим нест (гарчанде ки дар асл, RPC метавонад бо роҳҳои гуногун анҷом дода шавад, мо ба ин бармегардем) - аммо дар бораи Пок будани мафҳумҳои Математикаи намудҳои абстрактӣ аз олами осмонӣ чӣ гуфтан мумкин аст? .. Тугмаро ба даст гирифт - то мувофиқат кунед.

Ва ниҳоят, дар бораи хондан чӣ гуфтан мумкин аст? Хуб, дар он ҷо, умуман, ман мехоҳам шарҳ онро дуруст дар схема дошта бошед (боз, он дар схемаи JSON аст), аммо агар он аллакай бо он сахтгир шуда бошад, пас дар бораи паҳлӯи амалӣ чӣ гуфтан мумкин аст - ҳадди аққал тамошо кардани фарқиятҳо ҳангоми навсозӣ оддӣ аст? Худатон бубинед мисолҳои воқеӣ:

-channelFull#76af5481 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
+channelFull#1c87a71a flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;

ё

-message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
+message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;

Ба касе маъқул аст, аммо GitHub, масалан, таъкид кардани тағирот дар дохили чунин хатҳои дарозро рад мекунад. Бозии "10 фарқиятро пайдо кунед" ва он чизеро, ки майна фавран мебинад, ин аст, ки ибтидо ва интиҳо дар ҳарду мисол якхелаанд, шумо бояд дар ҷое дар мобайн дилгирона хонед ... Ба андешаи ман, ин танҳо дар назария нест, балки ба таври визуалӣ ба назар мерасад ифлос ва бетартиб.

Зимнан, дар бораи тозагии назария. Чаро майдонҳои бит лозиманд? Оё онҳо ба назар намерасанд бӯй аз нуктаи назари назарияи тип бад аст? Шарҳро дар версияҳои қаблии схема дидан мумкин аст. Дар аввал, бале, чунин буд, барои ҳар як атса навъи нав ба вуҷуд омад. Ин рудиментҳо то ҳол дар ин шакл мавҷуданд, масалан:

storage.fileUnknown#aa963b05 = storage.FileType;
storage.filePartial#40bc6f52 = storage.FileType;
storage.fileJpeg#7efe0e = storage.FileType;
storage.fileGif#cae1aadf = storage.FileType;
storage.filePng#a4f63c0 = storage.FileType;
storage.filePdf#ae1e508d = storage.FileType;
storage.fileMp3#528a0677 = storage.FileType;
storage.fileMov#4b09ebbc = storage.FileType;
storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;

Аммо ҳоло тасаввур кунед, ки агар шумо дар сохтори худ 5 майдони ихтиёрӣ дошта бошед, пас барои ҳамаи имконоти имконпазир ба шумо 32 намуд лозим аст. таркиши комбинат. Ҳамин тавр, покии булӯрии назарияи TL бори дигар ба хари оҳанини воқеияти сахти сериализатсия бархӯрд.

Илова бар ин, дар ҷойҳо худи ин бачаҳо чопкунии худро вайрон мекунанд. Масалан, дар MTProto (боби оянда) посухро бо Gzip фишурдан мумкин аст, ҳама чиз оқилона аст - ба истиснои вайрон кардани қабатҳо ва схема. Боре, ва на худи RpcResult, балки мундариҷаи онро даравид. Хуб, чаро ин корро кардан?.. Маҷбур шудам, ки асобаро буридам, то компрессия дар ҳама ҷо кор кунад.

Ё мисоли дигар, мо як бор хато ёфтем - фиристода InputPeerUser ба ҷои InputUser. Ё баръакс. Аммо он кор кард! Ин аст, ки сервер ба намуди парвое надошт. Ин чӣ гуна буда метавонад? Ҷавоб, шояд аз пораҳои код аз telegram-cli дархост карда шавад:

  if (tgl_get_peer_type (E->id) != TGL_PEER_CHANNEL || (C && (C->flags & TGLCHF_MEGAGROUP))) {
    out_int (CODE_messages_get_history);
    out_peer_id (TLS, E->id);
  } else {    
    out_int (CODE_channels_get_important_history);

    out_int (CODE_input_channel);
    out_int (tgl_get_peer_id (E->id));
    out_long (E->id.access_hash);
  }
  out_int (E->max_id);
  out_int (E->offset);
  out_int (E->limit);
  out_int (0);
  out_int (0);

Ба ибораи дигар, дар ин ҷо силсиласозӣ анҷом дода мешавад ДАСТИ, рамзи тавлид нашудааст! Шояд сервер ба ҳамин тариқ амалӣ карда шавад?.. Аслан, ин кор агар як маротиба анҷом дода шавад, аммо чӣ тавр шумо метавонед онро баъдтар бо навсозӣ дастгирӣ кунед? Магар ин нақша барои ҳамин набуд? Ва он гоҳ мо ба саволи навбатӣ мегузарем.

Версиясозӣ. Қабатҳо

Чаро версияҳои схемаро қабатҳо меноманд, танҳо дар асоси таърихи схемаҳои нашршуда тахмин кардан мумкин аст. Аз афташ, дар аввал ба назари муаллифон чунин менамуд, ки корҳои асосиро метавон аз рӯи нақшаи бетағйир анҷом дод ва танҳо дар ҳолати зарурӣ ба дархостҳои мушаххас нишон медиҳад, ки онҳо аз рӯи версияи дигар иҷро карда мешаванд. Аслан, ҳатто як идеяи хуб - ва иродаи нав, ба тавре ки гӯё "омехта мешавад", қабати кӯҳна мешавад. Аммо биёед бубинем, ки он чӣ гуна сурат гирифт. Дуруст аст, ки аз аввал дидан мумкин набуд - ин хандаовар аст, аммо схемаи қабати асосӣ вуҷуд надорад. Қабатҳо дар 2 оғоз ёфтанд. Ҳуҷҷатҳо ба мо дар бораи хусусияти махсуси TL нақл мекунанд:

Агар муштарӣ қабати 2-ро дастгирӣ кунад, пас конструктори зерин бояд истифода шавад:

invokeWithLayer2#289dd1f6 {X:Type} query:!X = X;

Дар амал, ин маънои онро дорад, ки пеш аз ҳар як занги API, як int бо арзиш 0x289dd1f6 бояд пеш аз рақами усул илова карда шавад.

Хуб садо медиҳад. Аммо баъд чӣ шуд? Баъд омад

invokeWithLayer3#b7475268 query:!X = X;

Пас оянда чӣ аст? Чун тахмин кардан осон аст

invokeWithLayer4#dea0d430 query:!X = X;

Хандаовар? Не, хандан барвакт аст, фикр кунед, ки чй ҳар як дархост аз қабати дигар бояд дар чунин намуди махсус печонида шавад - агар шумо ҳамаашон гуногун бошанд, онҳоро боз чӣ гуна фарқ кардан мумкин аст? Ва илова кардани ҳамагӣ 4 байт дар пеш як усули хеле муассир аст. Пас

invokeWithLayer5#417a57ae query:!X = X;

Аммо маълум аст, ки пас аз чанде он ба ягон бачана табдил меёбад. Ва ҳалли он омад:

Навсозӣ: Аз қабати 9 сар карда, усулҳои ёрирасон invokeWithLayerN якҷоя истифода бурдан мумкин аст initConnection

Ура! Пас аз 9 версия, мо ниҳоят ба он чизе расидем, ки дар протоколҳои интернетӣ дар солҳои 80-ум анҷом дода шуда буданд - музокироти версияи як маротиба дар оғози пайвастшавӣ!

Пас оянда чӣ мешавад?..

invokeWithLayer10#39620c41 query:!X = X;
...
invokeWithLayer18#1c900537 query:!X = X;

Ва акнун шумо метавонед хандед. Танҳо пас аз 9 қабати дигар, ниҳоят як конструктори универсалӣ бо рақами версия илова карда шуд, ки онро танҳо як маротиба дар оғози пайвастшавӣ даъват кардан лозим аст ва маънои дар қабатҳо аз байн рафтааст, ҳоло он танҳо як версияи шартӣ аст, ба монанди дар хама чо дигар. Масъала ҳал шуд.

Дуруст?..

Василий, [16.07.18 14:01] Рӯзи ҷумъа ман фикр кардам:
Телесервер воқеаҳоро бе дархост мефиристад. Дархостҳо бояд дар InvokeWithLayer печонида шаванд. Сервер навсозиҳоро ҷамъ намекунад, сохтор барои печонидани посухҳо ва навсозиҳо вуҷуд надорад.

Онхое. муштарӣ наметавонад қабатеро, ки дар он навсозӣ мехоҳад, муайян кунад

Вадим Гончаров, [16.07.18 14:02] Оё InvokeWithLayer аслан асобағал нест?

Василий, [16.07.18 14:02] Ин ягона роҳ аст

Вадим Гончаров, [16.07.18 14:02], ки аслан бояд маънои қабатро дар оғози ҷаласа дошта бошад

Дар омади гап, аз ин бармеояд, ки пастравии муштарӣ пешбинӣ нашудааст

Навсозиҳо, яъне. навъи Updates дар схема, ин он чизест, ки сервер ба муштарӣ на дар посух ба дархости API, балки ҳангоми рух додани ҳодиса худаш мефиристад. Ин як мавзӯи мураккабест, ки дар мақолаи дигар баррасӣ хоҳад шуд, аммо ҳоло муҳим аст, ки донед, ки сервер ҳатто ҳангоми офлайн будани муштарӣ Навсозиҳо ҷамъ мекунад.

Ҳамин тариқ, ҳангоми рад кардани печонидани ҳар яке бастаро нишон медиҳад, ки версияи онро нишон диҳад, бинобар ин мантиқан мушкилоти зерини имконпазир ба миён меоянд:

  • сервер пеш аз он ки муштарӣ гӯяд, ки кадом версияи онро дастгирӣ мекунад, ба муштарӣ навсозиҳо мефиристад
  • пас аз навсозии муштарӣ чӣ бояд кард?
  • ки кафолат медиҳадки фикри сервер дар бораи шумораи қабат дар раванди тағйир намеёбад?

Оё шумо фикр мекунед, ки ин тафаккури сирф назариявӣ аст ва дар амал ин тавр шуда наметавонад, зеро сервер дуруст навишта шудааст (ба ҳар сурат, он хуб санҷида шудааст)? Ха! Новобаста аз он ки чӣ тавр!

Махз ба хамин чиз мо дар мохи август дучор омадем. Рӯзи 14 август паёмҳо пайдо шуданд, ки дар серверҳои Telegram чизе нав карда мешавад ... ва сипас дар гузоришҳо:

2019-08-15 09:28:35.880640 MSK warn  main: ANON:87: unknown object type: 0x80d182d1 at TL/Object.pm line 213.
2019-08-15 09:28:35.751899 MSK warn  main: ANON:87: unknown object type: 0xb5223b0f at TL/Object.pm line 213.

ва он гоҳ чанд мегабайт пайҳои стек (хуб, дар айни замон, сабти ном сабт карда шуд). Дар ниҳоят, агар чизе дар TL-и шумо эътироф карда нашавад - он аз рӯи имзоҳо дуӣ аст, минбаъд дар ҷараён ҲАМАИ меравад, рамзкушоӣ ғайриимкон мегардад. Дар чунин вазъият чй бояд кард?

Хуб, аввалин чизе, ки ба сари ҳар кас меояд, ин аст, ки ҷудо ва дубора кӯшиш кунед. Кумак накард. Мо Google CRC32-ро ҷустуҷӯ кардем - инҳо объектҳои схемаи 73 буданд, гарчанде ки мо дар схемаи 82 кор кардем. Мо ба гузоришҳо бодиққат назар мекунем - аз ду схемаи гуногун идентификаторҳо мавҷуданд!

Шояд мушкилот сирф дар муштарии ғайрирасмии мо бошад? Не, мо Telegram Desktop 1.2.17-ро иҷро мекунем (версияи бо як қатор тақсимоти Linux таъминшуда), он ба қайди Истисно менависад: навъи MTP ғайричашмдошт ID #b5223b0f дар MTPMessageMedia хонда мешавад…

Интиқод аз протокол ва равишҳои ташкилии Telegram. Қисми 1, техникӣ: таҷрибаи навиштани муштарӣ аз сифр - TL, MT

Google нишон дод, ки мушкилоти шабеҳ аллакай бо яке аз муштариёни ғайрирасмӣ рух додааст, аммо баъд рақамҳои версия ва мувофиқан фарзияҳо гуногун буданд ...

Пас, чӣ бояд кард? Василий ва ман ҷудо шудем: ӯ кӯшиш кард, ки схемаро ба 91 навсозӣ кунад, ман қарор додам, ки чанд рӯз интизор шавам ва 73 кӯшиш кунам. Ҳарду усул кор карданд, аммо азбаски онҳо эмпирикӣ ҳастанд, фаҳмиши он нест, ки чанд версияи шумо бояд ҷаҳида шавад. ё поён, на чӣ қадар вақт шумо бояд интизор шавед.

Баъдтар, ман тавонистам вазъро дубора такрор кунам: мо муштариро оғоз мекунем, онро хомӯш мекунем, схемаро ба қабати дигар дубора тартиб медиҳем, бозоғоз мекунем, мушкилотро дубора ҳал мекунем, ба пешина бармегардем - афсӯс, тағир додани схема ва бозоғоз кардани муштарӣ барои чанд муддат. дақиқа кӯмак хоҳад кард. Шумо омехтаи сохторҳои маълумотро аз қабатҳои гуногун мегиред.

Шарҳ? Тавре ки шумо метавонед аз нишонаҳои гуногуни ғайримустақим тахмин кунед, сервер аз намудҳои гуногуни равандҳо дар мошинҳои гуногун иборат аст. Эҳтимол, яке аз серверҳое, ки барои "буферсозӣ" масъул аст, он чизеро, ки болотар дода буданд, ба навбат мегузоранд ва онҳо онро бо схемае, ки дар замони тавлид буд, доданд. Ва то даме, ки ин навбат «пӯсида» буд, коре карда наметавонист.

Магар... аммо ин асобаги даҳшатбор аст?!.. Не, пеш аз он ки дар бораи андешаҳои девона фикр кунем, биёед ба коди муштариёни расмӣ назар андозем. Дар версияи Android, мо ягон таҳлилгари TL-ро намеёбем, аммо мо файли вазнинеро пайдо мекунем (github ранг кардани онро рад мекунад) бо (de) сериализатсия. Инҳоянд пораҳои код:

public static class TL_message_layer68 extends TL_message {
    public static int constructor = 0xc09be45f;
//...
//еще пачка подобных
//...
    public static class TL_message_layer47 extends TL_message {
        public static int constructor = 0xc992e15c;
        public static Message TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
            Message result = null;
            switch (constructor) {
                case 0x1d86f70e:
                    result = new TL_messageService_old2();
                    break;
                case 0xa7ab1991:
                    result = new TL_message_old3();
                    break;
                case 0xc3060325:
                    result = new TL_message_old4();
                    break;
                case 0x555555fa:
                    result = new TL_message_secret();
                    break;
                case 0x555555f9:
                    result = new TL_message_secret_layer72();
                    break;
                case 0x90dddc11:
                    result = new TL_message_layer72();
                    break;
                case 0xc09be45f:
                    result = new TL_message_layer68();
                    break;
                case 0xc992e15c:
                    result = new TL_message_layer47();
                    break;
                case 0x5ba66c13:
                    result = new TL_message_old7();
                    break;
                case 0xc06b9607:
                    result = new TL_messageService_layer48();
                    break;
                case 0x83e5de54:
                    result = new TL_messageEmpty();
                    break;
                case 0x2bebfa86:
                    result = new TL_message_old6();
                    break;
                case 0x44f9b43d:
                    result = new TL_message_layer104();
                    break;
                case 0x1c9b1027:
                    result = new TL_message_layer104_2();
                    break;
                case 0xa367e716:
                    result = new TL_messageForwarded_old2(); //custom
                    break;
                case 0x5f46804:
                    result = new TL_messageForwarded_old(); //custom
                    break;
                case 0x567699b3:
                    result = new TL_message_old2(); //custom
                    break;
                case 0x9f8d60bb:
                    result = new TL_messageService_old(); //custom
                    break;
                case 0x22eb6aba:
                    result = new TL_message_old(); //custom
                    break;
                case 0x555555F8:
                    result = new TL_message_secret_old(); //custom
                    break;
                case 0x9789dac4:
                    result = new TL_message_layer104_3();
                    break;

ё

    boolean fixCaption = !TextUtils.isEmpty(message) &&
    (media instanceof TLRPC.TL_messageMediaPhoto_old ||
     media instanceof TLRPC.TL_messageMediaPhoto_layer68 ||
     media instanceof TLRPC.TL_messageMediaPhoto_layer74 ||
     media instanceof TLRPC.TL_messageMediaDocument_old ||
     media instanceof TLRPC.TL_messageMediaDocument_layer68 ||
     media instanceof TLRPC.TL_messageMediaDocument_layer74)
    && message.startsWith("-1");

Ҳмм... ин девона ба назар мерасад. Аммо, эҳтимол, ин рамзи тавлидшуда аст, пас хуб? .. Аммо он бешубҳа ҳама версияҳоро дастгирӣ мекунад! Дуруст, маълум нест, ки чаро ҳама чиз дар як тӯда ва чатҳои пинҳонӣ ва ҳар гуна _old7 гӯё ба насли мошини монанд нест ... Бо вуҷуди ин, бештар аз ҳама ман чормащз аз рафт

TL_message_layer104
TL_message_layer104_2
TL_message_layer104_3

Бачаҳо, оё шумо ҳатто дар дохили як қабат қарор қабул карда наметавонед?! Хуб, хуб, «ду», гӯем, бо хато озод шуданд, хуб, ҳамин тавр мешавад, аммо СЕ?.. Дарҳол боз дар ҳамон раке? Ин чӣ гуна порнография аст, бахшиш? ..

Воқеан, дар манбаҳои Telegram Desktop чунин ҳодиса рӯй медиҳад - агар ин тавр бошад, ва якчанд супоришҳои пай дар пай ба схема рақами қабати онро тағир намедиҳанд, балки чизеро ислоҳ мекунанд. Дар шароите, ки манбаи расмии маълумот барои схема мавҷуд нест, ман метавонам онро аз куҷо дастрас кунам, ба истиснои манбаъҳои расмии муштарӣ? Ва шумо онро аз он ҷо мегиред, шумо наметавонед боварӣ ҳосил кунед, ки схема комилан дуруст аст, то даме ки шумо ҳамаи усулҳоро санҷед.

Чӣ тавр инро ҳатто санҷидан мумкин аст? Умедворам, ки мухлисони озмоишҳо, функсионалӣ ва дигар дар шарҳҳо мубодила хоҳанд кард.

Хуб, биёед як пораи дигари кодро бубинем:

public static class TL_folders_deleteFolder extends TLObject {
    public static int constructor = 0x1c295881;

    public int folder_id;

    public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
        return Updates.TLdeserialize(stream, constructor, exception);
    }

    public void serializeToStream(AbstractSerializedData stream) {
        stream.writeInt32(constructor);
        stream.writeInt32(folder_id);
    }
}

//manually created

//RichText start
public static abstract class RichText extends TLObject {
    public String url;
    public long webpage_id;
    public String email;
    public ArrayList<RichText> texts = new ArrayList<>();
    public RichText parentRichText;

    public static RichText TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
        RichText result = null;
        switch (constructor) {
            case 0x1ccb966a:
                result = new TL_textPhone();
                break;
            case 0xc7fb5e01:
                result = new TL_textSuperscript();
                break;

Ин шарҳи "дастӣ сохташуда" дар ин ҷо нишон медиҳад, ки танҳо як қисми ин файл бо даст навишта шудааст (метавонед даҳшати нигоҳубинро тасаввур кунед?) ва боқимонда мошин тавлид карда мешавад. Аммо, пас саволи дигар ба миён меояд - ки манбаъҳо дастрасанд пурра не (a la blobs дар зери GPL дар ядрои Linux), аммо ин аллакай мавзӯи қисми дуюм аст.

Аммо басанда. Биёед ба протокол гузарем, ки дар болои он ҳамаи ин силсиласозӣ таъқиб карда мешавад.

MT Proto

Пас биёед кушоем тавсифи умумӣ и тавсифи муфассали протокол ва аввалин чизе, ки мо пешпо мехӯрем, истилоҳот аст. Ва бо фаровонии ҳама чиз. Умуман, ин як тамғаи тиҷоратии Telegram аст - барои занг задан дар ҷойҳои гуногун бо роҳҳои гуногун ё чизҳои гуногун бо як калима ё баръакс (масалан, дар API-и сатҳи баланд, агар шумо бастаи стикерро бинед - ин он чизе нест, ки шумо фикр мекардед).

Масалан, "паём" (паём) ва "сессия" (сессия) - дар ин ҷо онҳо чизи дигареро дар назар доранд, ки дар интерфейси муқаррарии муштарии Telegram фарқ мекунанд. Хуб, бо паём ҳама чиз равшан аст, онро метавон аз рӯи OOP маънидод кард, ё танҳо калимаи "баста" номида мешавад - ин сатҳи пасти интиқол аст, ҳамон паёмҳо, ки дар интерфейс нестанд, бисёранд. аз хизматрасонй. Аммо сессия ... аммо чизи аввал.

қабати нақлиёт

Аввалин чизест, ки нақлиёт аст. Ба мо дар бораи 5 вариант гуфта мешавад:

  • TCP
  • Вебсокет
  • Вебсокет тавассути HTTPS
  • HTTP
  • HTTPS

Василий, [15.06.18/15/04 XNUMX:XNUMX] Ва инчунин нақлиёти UDP вуҷуд дорад, аммо он ҳуҷҷатгузорӣ нашудааст

Ва TCP дар се вариант

Якум ба UDP бар TCP монанд аст, ҳар як баста рақами пайдарпай ва crc дорад
Чаро хондани докҳо дар ароба ин қадар дарднок аст?

Хуб, ҳоло TCP аллакай дар 4 вариант:

  • Ихтисоршуда
  • мобайнӣ
  • мобайнии пуркардашуда
  • пур

Хуб, миёнарави Padded барои MTProxy, ин баъдтар бо сабаби рӯйдодҳои маълум илова карда шуд. Аммо чаро ду версияи дигар (дар маҷмӯъ се), вақте ки яке метавонист? Ҳамаи чорҳо танҳо дар чӣ гуна муқаррар кардани дарозӣ ва сарбории аслии MTProto, ки минбаъд муҳокима хоҳанд шуд, фарқ мекунанд:

  • дар ихтисоршуда он 1 ё 4 байт аст, аммо на 0xef пас тан
  • дар миёнаравӣ ин 4 байт дарозӣ ва майдон аст ва бори аввал муштарӣ бояд ирсол кунад 0xeeeeeeee Барои нишон додани он, ки миёнарав аст
  • дар Full, аз ҳама одаткунанда, аз нуқтаи назари як шабакавӣ: дарозӣ, рақами пайдарпай ва НЕ ОНест, ки асосан MTProto, бадан, CRC32. Бале, ҳамаи ин тавассути TCP. Ки ба мо интиқоли боэътимодро дар шакли ҷараёни пайдарпайи байтҳо таъмин мекунад, ҳеҷ гуна пайдарпай лозим нест, бахусус чекҳо. Хуб, ҳоло ба ман эътироз хоҳанд кард, ки TCP дорои маблағи санҷиши 16-бит аст, бинобар ин, фасоди додаҳо рух медиҳад. Аҷоиб, ба истиснои он ки мо воқеан як протоколи криптографии дорои хэшҳои зиёда аз 16 байт дорем, ҳамаи ин хатогиҳо - ва ҳатто бештар аз он - дар номутобиқатии SHA дар сатҳи баландтар дучор хоҳанд шуд. Дар CRC32 дар ин бора ягон нуктае нест.

Биёед Ихтисоршударо, ки дар он як байт дарозӣ имконпазир аст, бо миёнаравӣ муқоиса кунем, ки "Дар сурати зарурати ҳамоҳангсозии додаҳои 4-байтӣ" -ро асоснок мекунад, ки ин хеле сафсата аст. Гумон меравад, ки барномасозони Telegram он қадар беақл ҳастанд, ки маълумотро аз розетка ба буфери мувофиқ хонда наметавонанд? Шумо ба ҳар ҳол бояд ин корро кунед, зеро хондан метавонад ба шумо дилхоҳ миқдори байтҳоро баргардонад (ва инчунин серверҳои прокси мавҷуданд, масалан ...). Ё, аз тарафи дигар, чаро бо Ихтисоршуда ташвиш мекашем, агар мо то ҳол аз 16 байт пурборҳои калон дошта бошем - 3 байтро сарфа кунед баъзан ?

Чунин таассурот пайдо мешавад, ки Николай Дуров ба ихтироъ кардани велосипедҳо, аз ҷумла протоколҳои шабакавӣ, бе зарурати амалӣ хеле дӯст медорад.

Дигар имконоти нақлиёт, аз ҷумла. Web ва MTProxy, мо ҳоло баррасӣ нахоҳем кард, шояд дар як паёми дигар, агар дархост вуҷуд дошта бошад. Биёед ҳоло дар бораи ин MTProxy ёдовар шавем, ки пас аз нашри он дар соли 2018 провайдерҳо зуд маҳкам кардани онро ёд гирифтанд, ки барои он пешбинӣ шудааст. блоки гардиш, дар бораи андозаи пакет! Ва инчунин далели он, ки сервери MTProxy (боз аз ҷониби Уолтман) дар C навишта шудааст, ба таври нолозим ба мушаххасоти Linux алоқаманд буд, гарчанде ки он тамоман талаб карда нашуд (Фил Кулин тасдиқ мекунад) ва сервери шабеҳ дар Go ё Node.js камтар аз сад сатр мувофиқат мекунад.

Вале мо дар бораи саводнокии техникии ин одамон дар охири бахш баъди баррасии дигар масъалахо хулоса мебарорем. Ҳоло, биёед ба қабати 5-уми OSI, сеанс, ки онҳо сессияи MTProto-ро дар он ҷойгир кардаанд, гузарем.

Калидҳо, паёмҳо, сессияҳо, Diffie-Hellman

Онҳо онро дар он ҷо комилан дуруст гузоштаанд ... Сеанс ҳамон сессияест, ки дар интерфейси зери сессияҳои фаъол намоён аст. Аммо ба тартиб.

Интиқод аз протокол ва равишҳои ташкилии Telegram. Қисми 1, техникӣ: таҷрибаи навиштани муштарӣ аз сифр - TL, MT

Дар ин ҷо мо як сатри байтҳои дарозии маълумро аз қабати нақлиёт гирифтем. Ин ё паёми рамзгузоришуда ё матни равшан аст - агар мо то ҳол дар марҳилаи асосии гуфтушунид бошем ва воқеан онро иҷро карда истодаем. Мо дар бораи кадоме аз маҷмӯи мафҳумҳое, ки «калид» ном доранд, сухан меронем? Биёед ин масъаларо барои худи дастаи Telegram равшан кунем (барои тарҷумаи ҳуҷҷатҳои худам аз инглисӣ ё мағзи хастаи соати 4-и саҳар узр мепурсам, баъзе ибораҳоро ҳамон тавр гузоштан осонтар буд):

Ду объект номида мешаванд сессия - яке дар интерфейси муштариёни расмӣ дар зери "сеансҳои ҷорӣ", ки дар он ҳар як сессия ба тамоми дастгоҳ / OS мувофиқат мекунад.
Дуюм - Сеанси MTProto, ки дар он рақами пайдарпайии паём (ба маънои сатҳи паст) дорад ва кадоме метавонад байни пайвастҳои гуногуни TCP давом кунад. Якчанд сессияҳои MTProto-ро дар як вақт метавон танзим кард, масалан, барои суръат бахшидани зеркашии файл.

Дар байни ин ду љаласањои мафхум аст ваколат. Дар мавриди таназзул метавон гуфт Сеанси UI ҳамон тавре аст ваколатАммо афсус, ки ин мураккаб аст. Мо назар мекунем:

  • Корбар дар дастгоҳи нав аввал тавлид мекунад auth_key ва онро ба ҳисоб, масалан, тавассути SMS бастааст - барои ҳамин ваколат
  • Ин дар дохили аввалин рӯй дод Сеанси MTProto, ки дорад session_id дар дохили худ.
  • Дар ин марҳила, комбинатсияи ваколат и session_id ном бурдан мумкин буд мисол - ин калима дар ҳуҷҷатҳо ва рамзи баъзе муштариён пайдо шудааст
  • Пас, муштарӣ метавонад кушода шавад якчанд Сеансҳои MTProto зери ҳамин auth_key - ба ҳамон DC.
  • Пас аз як рӯз муштарӣ бояд файлеро аз он дархост кунад дигар DC - ва барои ин DC як нав тавлид мешавад auth_key !
  • Ба система бигӯед, ки ин як корбари нав нест, балки ҳамон як аст ваколат (Сеанси UI), муштарӣ зангҳои API-ро истифода мебарад auth.exportAuthorization дар хона DC auth.importAuthorization дар DC нав.
  • Бо вуҷуди ин, метавонад якчанд кушода бошад Сеансҳои MTProto (ҳар як бо худ session_id) ба ин DC нав, дар зери вай auth_key.
  • Дар ниҳоят, муштарӣ метавонад махфияти комили пешгириро талаб кунад. Хар auth_key ки Доимӣ калиди - дар як DC - ва муштарӣ метавонад занг занад auth.bindTempAuthKey барои истифода муваққатӣ auth_key - ва боз, танҳо як temp_auth_key дар як DC, умумӣ барои ҳама Сеансҳои MTProto ба ин DC.

огоҳӣ диҳед, ки намак (ва намакҳои оянда) низ як auth_key ки. байни ҳама тақсим карда шуд Сеансҳои MTProto ба ҳамон DC.

"Байни пайвастҳои гуногуни TCP" чӣ маъно дорад? Ин маънои онро дорад, ки ин чизе монанди куки авторизатсия дар вебсайт - он пайвастагиҳои зиёди TCP ба ин серверро нигоҳ медорад (зинда мемонад), аммо рӯзе он бад мешавад. Танҳо бар хилофи HTTP, дар MTProto, дар дохили сеанс, паёмҳо пайдарпай рақамгузорӣ карда мешаванд ва тасдиқ карда мешаванд, онҳо ба нақб ворид шуданд, пайвастшавӣ канда шуд - пас аз барқарор кардани пайвасти нав, сервер ҳама чизро дар ин сеанс мефиристад, ки он дар сессия нарасидааст. пайвасти пешинаи TCP.

Бо вуҷуди ин, маълумоти дар боло овардашуда як фишурда пас аз чанд моҳи мурофиаи судӣ аст. Дар ҳамин ҳол, оё мо муштарии худро аз сифр амалӣ мекунем? — ба аввал бармегардем.

Пас мо тавлид мекунем auth_key ба версияҳои Diffie-Hellman аз Telegram. Биёед кӯшиш кунем, ки ҳуҷҷатҳоро фаҳмем ...

Василий, [19.06.18/20/05 1:255] data_with_hash := SHAXNUMX(маълумот) + маълумот + (ҳар байтҳои тасодуфӣ); чунон ки дарозии он ба XNUMX байт баробар аст;
encrypted_data := RSA(маълумот_бо_хеш, сервер_публикӣ); рақами дарозии 255-байтӣ (индиан калон) ба қудрати зарурӣ бар модули зарурӣ расонида мешавад ва натиҷа ҳамчун рақами 256-байт нигоҳ дошта мешавад.

Онҳо каме доруи DH гирифтанд

Ба DH одами солим монанд нест
Дар dx ду калиди умумӣ вуҷуд надорад

Хуб, дар ниҳоят, мо инро фаҳмидем, аммо таҳшин боқӣ монд - далели кор аз ҷониби муштарӣ иҷро карда мешавад, ки ӯ тавонист рақамро ба омилҳо ҷудо кунад. Навъи муҳофизат аз ҳамлаҳои DoS. Ва калиди RSA танҳо як маротиба дар як самт, аслан барои рамзгузорӣ истифода мешавад new_nonce. Аммо дар ҳоле ки ин амалиёти ба назар содда муваффақ аст, шумо бояд бо чӣ рӯ ба рӯ шавед?

Василий, [20.06.18 00:26] Ман то ҳол ба дархости замима нарасидам

Ман ба DH дархост фиристодам

Ва, дар док дар нақлиёт навишта шудааст, ки он метавонад бо 4 байт рамзи хато ҷавоб диҳад. Ва тамом

Хуб, ӯ ба ман гуфт -404, пас чӣ?

Ман ба ӯ муроҷиат мекунам: "эфинати худро бо калиди сервер бо изи ангушти фалон ва фалон рамзгузорӣ кунед, ман DH мехоҳам" ва он беақлона ҷавоб медиҳад 404

Шумо дар бораи чунин посухи сервер чӣ фикр мекардед? Чӣ бояд кард? Касе нест, ки пурсад (вале дар ин бора бештар дар қисми дуюм).

Дар ин чо тамоми манфиати док ба кор аст

Дигар кор надорам, ман танҳо орзу мекардам, ки рақамҳоро пасу пеш табдил диҳам

Ду рақами 32-бит. Ман онҳоро мисли дигарон баста кардам

Аммо не, ин дуест, ки шумо аввал дар як саф ҳамчун BE лозиманд

Вадим Гончаров, [20.06.18 15:49] ва аз ин 404?

Василий, [20.06.18 15:49] ҲА!

Вадим Гончаров, [20.06.18 15:50] бинобар ин ман намефаҳмам, ки ӯ чиро "наёфтааст"

Василий, [20.06.18 15:50] тахминан

Ман чунин таҷзияро ба тақсимкунандагони оддӣ наёфтам%)

Ҳатто гузориш додани хатогиҳо азхуд карда нашудааст

Василий, [20.06.18 20:18] Оҳ, MD5 низ ҳаст. Аллакай се hashes гуногун

Изи ангушти калидӣ ба таври зерин ҳисоб карда мешавад:

digest = md5(key + iv)
fingerprint = substr(digest, 0, 4) XOR substr(digest, 4, 4)

SHA1 ва sha2

Пас биёед гузорем auth_key Мувофиқи Диффи-Хеллман андозаи 2048 бит ба даст овардем. Баъд чӣ? Пас мо мефаҳмем, ки 1024 битҳои поёнии ин калид ба ҳеҷ ваҷҳ истифода намешаванд ... аммо биёед ҳоло дар ин бора фикр кунем. Дар ин қадам, мо бо сервер сирри муштарак дорем. Аналоги сессияи TLS таъсис дода шудааст, ки ин тартиби хеле гаронарзиш аст. Аммо сервер дар бораи кӣ будани мо чизе намедонад! Ҳанӯз не, воқеан иҷозат. Онхое. агар шумо бо истилоҳи "логин-парол" фикр мекардед, зеро он қаблан дар ICQ буд, ё ҳадди аққал "калиди воридшавӣ", ба мисли SSH (масалан, дар баъзе gitlab / github). Мо беном шудем. Ва агар сервер ба мо ҷавоб диҳад, "ин рақамҳои телефонӣ аз ҷониби DC-и дигар хидмат мекунанд"? Ё ҳатто "рақами телефони шумо мамнӯъ аст"? Беҳтарин чизе, ки мо карда метавонем, ин захира кардани калид ба умеди он аст, ки он то ҳол муфид хоҳад буд ва то он вақт пӯсида намешавад.

Воқеан, мо онро бо қайду шартҳо «қабул кардем». Масалан, оё мо ба сервер эътимод дорем? Оё ӯ қалбакӣ? Мо ба санҷишҳои криптографӣ ниёз дорем:

Василий, [21.06.18 17:53] Онҳо ба муштариёни мобилӣ пешниҳод мекунанд, ки рақами 2кбитро барои содда тафтиш кунанд%)

Аммо тамоман равшан нест, нафеижоа

Василий, [21.06.18 18:02] Док намегӯяд, ки агар он оддӣ набошад, чӣ бояд кард

Нагуфтаанд. Биёед бубинем, ки муштарии расмии Android дар ин ҳолат чӣ кор мекунад? А ки ин (ва ҳа, тамоми файл дар он ҷо ҷолиб аст) - чунон ки мегӯянд, ман онро дар ин ҷо мегузорам:

278     static const char *goodPrime = "c71caeb9c6b1c9048e6c522f70f13f73980d40238e3e21c14934d037563d930f48198a0aa7c14058229493d22530f4dbfa336f6e0ac925139543aed44cce7c3720fd51f69458705ac68cd4fe6b6b13abdc9746512969328454f18faf8c595f642477fe96bb2a941d5bcd1d4ac8cc49880708fa9b378e3c4f3a9060bee67cf9a4a4a695811051907e162753b56b0f6b410dba74d8a84b2a14b3144e0ef1284754fd17ed950d5965b4b9dd46582db1178d169c6bc465b0d6ff9ca3928fef5b9ae4e418fc15e83ebea0f87fa9ff5eed70050ded2849f47bf959d956850ce929851f0d8115f635b105ee2e4e15d04b2454bf6f4fadf034b10403119cd8e3b92fcc5b";
279   if (!strcasecmp(prime, goodPrime)) {

Не, албатта дар он ҷо баъзе барои содда будани шумораҳо санҷишҳо мавҷуданд, аммо шахсан ман дигар дар соҳаи математика дониши кофӣ надорам.

Хуб, мо калиди усторо гирифтем. Барои ворид шудан, яъне. фиристодани дархостҳо, зарур аст, ки рамзгузории минбаъдаро аллакай бо истифода аз AES анҷом диҳед.

Калиди паём ҳамчун 128 битҳои миёнаи SHA256 мақоми паём (аз ҷумла сеанс, ID паём ва ғ.), аз ҷумла байтҳои пуркунӣ, ки бо 32 байт аз калиди авторизатсия гирифта шудааст, муайян карда мешавад.

Василий, [22.06.18 14:08] Калтакҳои миёна

Гирифтанд auth_key. Ҳама. Минбаъд онҳо ... аз докҳо маълум нест. Озод ҳис кунед, ки рамзи кушодаасосро омӯзед.

Аҳамият диҳед, ки MTProto 2.0 аз 12 то 1024 байт пуркунӣ талаб мекунад, ба ҳар ҳол ба шарте, ки дарозии паём ба 16 байт тақсим карда шавад.

Пас, чӣ қадар пурбор кардан лозим аст?

Ва ҳа, дар ин ҷо низ 404 дар сурати хатогӣ

Агар касе диаграмма ва матни ҳуҷҷатҳоро бодиққат омӯзад, ӯ пай бурд, ки дар он ҷо ягон MAC нест. Ва он AES дар баъзе режими IGE истифода мешавад, ки дар ҷои дигар истифода намешавад. Онҳо, албатта, дар ин бора дар FAQ-и худ менависанд... Дар ин ҷо худи калиди паём ҳамзамон хэши SHA-и маълумоти рамзкушошуда аст, ки барои тафтиши якпорчагӣ истифода мешавад - ва дар сурати номувофиқӣ, ҳуҷҷатҳо барои баъзе сабабҳо тавсия медиҳад, ки ба онҳо беэътиноӣ кунанд (аммо дар бораи амният чӣ гуфтан мумкин аст, ногаҳон моро мешиканад?).

Ман криптограф нестам, шояд дар ин реҷа дар ин ҳолат аз нуқтаи назари назариявӣ ягон бадӣ набошад. Аммо ман бешубҳа метавонам як масъалаи амалиро бо истифода аз мисоли Desktop Telegram номбар кунам. Он кэши маҳаллиро (ҳамаи ин D877F783D5D3EF8C) ҳамон тавре ки паёмҳо дар MTProto (танҳо дар ин ҳолат, версияи 1.0) рамзгузорӣ мекунад, яъне. аввал калиди паём, баъд худи маълумот (ва дар ҷое, ки калиди асосии калон auth_key 256 байт, ки бе он msg_key бефоида). Ҳамин тавр, мушкилот дар файлҳои калон намоён мешавад. Махз, шумо бояд ду нусхаи маълумотро нигоҳ доред - рамзгузорӣ ва рамзкушоӣ. Ва агар мегабайтҳо ё ҷараёнҳои видео вуҷуд дошта бошанд, масалан? .. Схемаҳои классикӣ бо MAC пас аз рамзгузорӣ ба шумо имкон медиҳанд, ки онро ҷараён ва фавран интиқол диҳед. Ва бо MTProto шумо бояд дар аввал тамоми паёмро рамзгузорӣ ё рамзкушоӣ кунед, танҳо баъд онро ба шабака ё диск интиқол диҳед. Аз ин рӯ, дар версияҳои охирини Telegram Desktop дар кэш дар user_data формати дигар аллакай истифода шудааст - бо AES дар ҳолати CTR.

Василий, [21.06.18/01/27 20:XNUMX AM] Оҳ, ман фаҳмидам, ки IGE чист: IGE аввалин кӯшиши "режими рамзгузории аутентификатсия" буд, ки аслан барои Kerberos буд. Ин кӯшиши ноком буд (он муҳофизати беайбиятро таъмин намекунад) ва бояд хориҷ карда шавад. Ин оғози ҷустуҷӯи XNUMX-солаи реҷаи рамзгузории аутентификатсия буд, ки кор мекунад, ки ба наздикӣ дар шеваҳои монанди OCB ва GCM ба анҷом расид.

Ва ҳоло далелҳо аз ҷониби ароба:

Дастаи паси Telegram, ки ба он Николай Дуров роҳбарӣ мекунад, аз шаш чемпиони ACM иборат аст, ки нисфи онҳо номзадҳои фанҳои математика мебошанд. Барои баровардани версияи кунунии MTProto ба онҳо тақрибан ду сол лозим шуд.

Чӣ хандаовар аст. Ду сол ба сатҳи поёнӣ

Ё мо метавонем танҳо tls гирем

Хуб, биёед бигӯем, ки мо рамзгузорӣ ва дигар нозукиҳоро анҷом додем. Оё мо метавонем дар ниҳоят дархостҳои сериалшудаи TL фиристем ва посухҳоро бесерия гардонем? Пас, чӣ бояд фиристода шавад ва чӣ тавр? Ана усул initConnectionшояд ин аст?

Василий, [25.06.18 18:46] Пайвастро оғоз мекунад ва маълумотро дар дастгоҳ ва замимаи корбар захира мекунад.

Он app_id, device_model, system_version, app_version ва lang_code -ро қабул мекунад.

Ва чанд савол

Ҳуҷҷатҳо чун ҳамеша. Озод ҳис кунед, ки манбаи кушодаро омӯзед

Агар бо invokeWithLayer ҳама чиз тақрибан равшан бошад, пас ин чист? Маълум мешавад, ки фарз мекунем, ки мо дорем - муштарӣ аллакай чизе дошт, ки аз сервер пурсад - дархосте ҳаст, ки мо онро фиристоданӣ будем:

Василий, [25.06.18/19/13 XNUMX:XNUMX] Мувофиқи код, занги аввал дар ин ахлот печонида шудааст ва худи ахлот дар invokewithlayer аст.

Чаро initConnection занги ҷудогона буда наметавонад, аммо бояд парпеч бошад? Бале, чунон ки маълум шуд, он бояд хар дафъа дар аввали хар як машгулият анчом дода шавад, на якдафъаина, мисли калиди асосй. Аммо! Онро корбари беиҷозат занг зада наметавонад! Дар ин ҷо мо ба марҳилае расидем, ки дар он татбиқ карда мешавад Ҳаминаш саҳифаи ҳуҷҷатгузорӣ - ва он ба мо мегӯяд, ки ...

Танҳо як қисми ками усулҳои API барои корбарони беиҷозат дастрас аст:

  • auth.sendCode
  • auth.resendCode
  • account.getPassword
  • auth.checkPassword
  • auth.checkPhone
  • auth.signUp
  • auth.signIn
  • auth.importAuthorization
  • help.getConfig
  • help.getNearestDc
  • help.getAppUpdate
  • help.getCdnConfig
  • langpack.getLangPack
  • langpack.getStrings
  • langpack.getDifference
  • langpack.getLanguages
  • langpack.getLanguage

Аввалин аз онхо auth.sendCode, ва он дархости аввалини арзишманд вуҷуд дорад, ки дар он мо api_id ва api_hash мефиристем ва пас аз он мо SMS бо код мегирем. Ва агар мо ба DC-и нодуруст расида бошем (масалан, рақамҳои телефони ин кишварро дигар хидмат мекунанд), пас мо бо рақами DC-и дилхоҳ хато мегирем. Барои фаҳмидани он ки мо бояд бо рақами DC ба кадом суроғаи IP пайваст шавем, ба мо кӯмак мекунад help.getConfig. Замоне ҳамагӣ 5 сабт буд, аммо пас аз рӯйдодҳои маъруфи соли 2018 шумораи онҳо ба таври назаррас афзоиш ёфт.

Акнун биёед ба ёд орем, ки мо дар ин марҳила ба сервери беном расидем. Оё танҳо гирифтани суроғаи IP хеле гарон нест? Чаро ин ва дигар амалиётҳоро дар қисми рамзнашудаи MTProto иҷро накунед? Ман эътирозеро мешунавам: "чӣ гуна метавон боварӣ ҳосил кард, ки РКН бо суроғаҳои қалбакӣ ҷавоб намедиҳад?". Ба ин хотир мо, ки дар асл, дар мизоҷони расмӣ калидҳои RSA дарунсохт, яъне. шумо метавонед танҳо подписать ин маълумот. Дар асл, ин аллакай барои маълумот дар бораи гузариш аз қулфҳо, ки муштариён тавассути каналҳои дигар мегиранд, анҷом дода шудааст (мантиқист, ки ин корро дар худи MTProto иҷро кардан мумкин нест, зеро шумо ба ҳар ҳол бояд донед, ки ба куҷо пайваст шудан лозим аст).

ДУРУСТ. Дар ин марҳилаи иҷозати муштарӣ, мо ҳанӯз ваколатдор нестем ва аризаи худро ба қайд нагирифтаем. Мо танҳо мехоҳем бубинем, ки сервер ба усулҳое, ки барои корбари беиҷозат дастрасанд, чӣ ҷавоб медиҳад. Ва инҷо…

Василий, [10.07.18 14:45] https://core.telegram.org/method/help.getConfig

config#7dae33e0 [...] = Config;
help.getConfig#c4f9186b = Config;

https://core.telegram.org/api/datacenter

config#232d5905 [...] = Config;
help.getConfig#c4f9186b = Config;

Дар схема, якум, дуюм меояд

Дар схемаи tdesktop, арзиши сеюм аст

Бале, аз он вақт инҷониб, албатта, ҳуҷҷатҳо нав карда шуданд. Ҳарчанд ба зудӣ он метавонад боз номарбуте гардад. Ва як таҳиягари навкор чӣ гуна бояд донад? Шояд агар аризаатонро ба қайд гиред, онҳо шуморо огоҳ мекунанд? Василий ин корро кард, аммо афсӯс, ки ба ӯ чизе фиристода нашудааст (боз дар ин бора дар қисми дуюм сӯҳбат мекунем).

... Шумо пай бурдед, ки мо аллакай ба ягон навъ ба API гузаштаем, яъне. ба сатҳи оянда ва чизе дар мавзӯи MTProto беҷавоб? Ҳеҷ чиз тааҷҷубовар нест:

Василий, [28.06.18/02/04 2:XNUMX AM] Мм, онҳо баъзе аз алгоритмҳоро дар eXNUMXe варақ зада истодаанд

Mtproto алгоритмҳои рамзгузорӣ ва калидҳоро барои ҳарду доменҳо ва инчунин каме сохтори печанда муайян мекунад

Аммо онҳо пайваста сатҳҳои гуногуни стекро омехта мекунанд, аз ин рӯ на ҳама вақт маълум аст, ки mtproto дар куҷо тамом шуд ва сатҳи оянда оғоз шуд.

Онҳо чӣ гуна омехта шудаанд? Хуб, дар ин ҷо ҳамон калиди муваққатӣ барои PFS аст, масалан (дар омади гап, Telegram Desktop намедонад, ки ин корро чӣ тавр анҷом диҳад). Он тавассути дархости API иҷро карда мешавад auth.bindTempAuthKey, яъне. аз сатҳи боло. Аммо дар айни замон, он ба рамзгузорӣ дар сатҳи поёнӣ халал мерасонад - пас аз он, масалан, шумо бояд онро дубора иҷро кунед initConnection ва ғайра, ин нест танҳо дархости муқаррарӣ. Алоҳида, он инчунин медиҳад, ки шумо метавонед танҳо як калиди муваққатӣ дар DC дошта бошед, гарчанде ки майдон auth_key_id дар ҳар як паём ба шумо имкон медиҳад, ки калидро ҳадди аққал ҳар як паём тағир диҳед ва сервер ҳуқуқ дорад калиди муваққатиро дар вақти дилхоҳ "фаромӯш кунад" - дар ин ҳолат чӣ бояд кард, ҳуҷҷатҳо намегӯянд ... хуб, чаро чанд калид доштан мумкин набуд, ба мисли маҷмӯи намакҳои оянда, аммо?..

Дар мавзӯи MTProto чанд чизи дигаре ҳастанд, ки бояд қайд кард.

Паёмҳои паёмӣ, msg_id, msg_seqno, эътирофҳо, пингҳо дар самти нодуруст ва дигар хосиятҳо

Чаро шумо бояд дар бораи онҳо донед? Зеро онҳо як сатҳ баландтар "мерезанд" ва шумо бояд ҳангоми кор бо API дар бораи онҳо донед. Фарз мекунем, ки мо ба msg_key таваҷҷӯҳ надорем, сатҳи поёнӣ ҳама чизро барои мо рамзкушоӣ кардааст. Аммо дар дохили маълумоти рамзкушошуда, мо майдонҳои зерин дорем (инчунин дарозии маълумот барои фаҳмидани он, ки пуркунӣ дар куҷост, аммо ин муҳим нест):

  • намак-int64
  • session_id - int64
  • message_id - int64
  • seq_no-int32

Ба ёд оред, ки барои тамоми DC танҳо як намак вуҷуд дорад. Чаро дар бораи вай медонед? На танҳо барои он ки дархост вуҷуд дорад get_future_salts, ки он мегӯяд, ки кадом фосилаҳо дуруст хоҳанд буд, аммо инчунин аз он сабаб, ки агар намаки шумо "пӯсида" бошад, паём (дархост) танҳо гум мешавад. Сервер, албатта, дар бораи намаки нав хабар медиҳад new_session_created - аммо бо кӯҳна ба шумо лозим меояд, ки бо ягон роҳ дубора фиристед, масалан. Ва ин савол ба меъмории барнома таъсир мерасонад.

Ба сервер иҷозат дода шудааст, ки сеансҳоро комилан тарк кунад ва бо ин роҳ бо сабабҳои зиёд посух диҳад. Дар асл, сессияи MTProto аз ҷониби муштарӣ чист? Ин ду рақам аст session_id и seq_no паёмҳо дар ин сессия. Хуб, ва пайвасти асосии TCP, албатта. Фарз мекунем, ки муштарии мо то ҳол намедонад, ки чӣ тавр бисёр корҳоро анҷом диҳад, ҷудошуда, аз нав пайваст. Агар ин зуд рӯй дод - сессияи кӯҳна дар пайвасти нави TCP идома ёфт, афзоиш диҳед seq_no минбаъд. Агар ин муддати тӯлонӣ гирад, сервер метавонад онро нест кунад, зеро дар паҳлӯяш он ҳам навбат аст, ки мо фаҳмидем.

Чӣ бояд бошад seq_no? Оҳ, ин саволи душвор аст. Кӯшиш кунед, ки ростқавлона фаҳмед, ки чӣ маъно дорад:

Паёми марбут ба мундариҷа

Паём, ки эътирофи возеҳро талаб мекунад. Инҳо ҳама корбар ва паёмҳои зиёди хидматиро дар бар мегиранд, амалан ҳама ба истиснои контейнерҳо ва изҳорот.

Рақами пайдарпайии паём (msg_seqno)

Рақами 32-битӣ баробар ба ду баробар аз шумораи паёмҳои "ба мундариҷа" (онҳое, ки тасдиқро талаб мекунанд ва махсусан онҳое, ки контейнер нестанд) аз ҷониби ирсолкунанда пеш аз ин паём сохта шудаанд ва баъдан ба як зиёд карда мешаванд, агар паёми ҷорӣ паёми марбут ба мундариҷа. Контейнер ҳамеша пас аз тамоми мундариҷаи он тавлид мешавад; аз ин рӯ, рақами пайдарпайии он аз рақамҳои пайдарпайии паёмҳои дар он мавҷудбуда зиёд ё баробар аст.

Ин чӣ гуна сирк аст бо афзоиши 1 ва сипас 2? .. Ман гумон мекунам, ки маънои аслӣ "бити паст барои ACK, боқимонда рақам аст" буд, аммо натиҷа комилан дуруст нест - махсусан , маълум мешавад, ки фиристодан мумкин аст якчанд тасдиқҳое, ки якхела доранд seq_no! Чӣ хел? Хуб, масалан, сервер ба мо чизе мефиристад, мефиристад ва мо худамон хомӯшем, мо танҳо бо паёмҳои тасдиқи хидмат дар бораи қабули паёмҳои ӯ ҷавоб медиҳем. Дар ин ҳолат, тасдиқҳои содиротии мо ҳамон рақами содиротӣ доранд. Агар шумо бо TCP шинос бошед ва фикр мекардед, ки ин як навъ девона садо медиҳад, аммо ба назар чунин менамояд, ки он чандон ваҳшӣ нест, зеро дар TCP seq_no тағйир намеёбад, ва тасдиқ меравад seq_no тарафи дигар — баъд ба хафа шудан шитобам. Тасдиқҳо ба MTProto меоянд ҲАМА ба seq_no, чунон ки дар TCP, аммо msg_id !

Ин чӣ аст msg_id, мухимтарини ин соха? Идентификатсияи беназири паём, тавре ки аз ном бармеояд. Он ҳамчун рақами 64-бит муайян карда мешавад, ки битҳои камтарини онҳо боз ҷодугарии сервер-на сервер доранд ва боқимонда тамғаи Unix аст, аз ҷумла қисми касрӣ, 32 бит ба тарафи чап кӯчонида шудааст. Онхое. тамғаи вақт (ва паёмҳое, ки вақтҳои хеле гуногун доранд, аз ҷониби сервер рад карда мешаванд). Аз ин бармеояд, ки дар маҷмӯъ, ин идентификаторест, ки барои муштарӣ глобалӣ аст. Дар ҳоле ки - дар хотир доред session_id - мо кафолат медиҳем: Дар ҳеҷ ҳолат паёме, ки барои як сессия пешбинӣ шудааст, ба ҷаласаи дигар фиристода намешавад. Яъне, маълум мешавад, ки аллакай вуҷуд дорад се сатҳ — сеанс, рақами сессия, ID-и паём. Чаро чунин мураккабии аз ҳад зиёд, ин асрор хеле бузург аст.

Ва ҳамин тавр, msg_id барои…

RPC: дархостҳо, ҷавобҳо, хатогиҳо. Тасдиқҳо.

Тавре ки шумо шояд пай бурдед, дар ягон ҷои схема ягон намуди махсус ё функсияи "дархости RPC" вуҷуд надорад, гарчанде ки ҷавобҳо мавҷуданд. Баъд аз ҳама, мо паёмҳои марбут ба мундариҷа дорем! Яъне, ягон паём метавонад дархост бошад! Ё набошад. Дар поёни кор, ҳар яке аст msg_id. Ва инҳоянд ҷавобҳо:

rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult;

Дар ин ҷо нишон дода мешавад, ки ин ҷавоб ба кадом паём аст. Аз ин рӯ, дар сатҳи болоии API, шумо бояд дар хотир доред, ки дархости шумо кадом рақамро дошт - ман фикр мекунам, шарҳ додан лозим нест, ки кор асинхронӣ аст ва дар як вақт якчанд дархостҳо вуҷуд доранд, ки ҷавобҳо ба онҳо дода мешаванд. бо ягон тартиб баргардонидан мумкин аст? Аслан, аз ин ва паёмҳои хатогиҳо, ба монанди ҳеҷ коргарон, меъмории паси онро метавон пайгирӣ кард: сервере, ки пайвасти TCP-ро бо шумо нигоҳ медорад, мувозинати фронт аст, он дархостҳоро ба пуштибонҳо равона мекунад ва онҳоро бозпас ҷамъ мекунад. message_id. Дар ин ҷо ҳама чиз равшан, мантиқӣ ва хуб ба назар мерасад.

Бале?.. Ва агар дар ин бора фикр кунед? Охир, худи вокуниши RPC низ майдон дорад msg_id! Оё мо бояд ба сервер фарёд занем "шумо ба ҷавоби ман ҷавоб намедиҳед!"? Ва ҳа, дар бораи тасдиқ чӣ буд? Дар бораи саҳифа паёмҳо дар бораи паёмҳо ба мо мегӯяд, ки чӣ аст

msgs_ack#62d6b459 msg_ids:Vector long = MsgsAck;

ва хар тараф бояд ин корро кунад. Аммо на ҳамеша! Агар шумо RpcResult гиред, он худ ба худ ҳамчун эътироф хизмат мекунад. Яъне, сервер метавонад ба дархости шумо бо MsgsAck посух диҳад, масалан, "Ман онро гирифтам". Дарҳол метавонад ба RpcResult ҷавоб диҳад. Он метавонад ҳарду бошад.

Ва ҳа, шумо ба ҳар ҳол бояд ҷавоб диҳед! Тасдиқ. Дар акси ҳол, сервер онро расониданашуда ҳисоб мекунад ва онро дубора ба шумо мепартояд. Ҳатто пас аз пайвастшавӣ. Аммо дар ин ҷо, албатта, саволи вақт-аут ба миён меояд. Биёед каме дертар ба онҳо назар кунем.

Дар айни замон, биёед хатогиҳои имконпазирро дар иҷрои дархост баррасӣ кунем.

rpc_error#2144ca19 error_code:int error_message:string = RpcError;

Оҳ, касе хитоб мекунад, дар ин ҷо формати инсонӣ бештар аст - хат вуҷуд дорад! Шитоб накун. Ин ҷо рӯйхати хатогиҳовале албатта пурра нест. Аз он мо мефаҳмем, ки код − аст чизе монанди Хатогиҳои HTTP (хуб, албатта, семантикаи ҷавобҳо риоя карда намешаванд, дар баъзе ҷойҳо онҳо бо рамзҳо ба таври тасодуфӣ тақсим карда мешаванд) ва сатр ба монанди КАПИТАЛ_ҲАРФ_ВА_РАҚАМҲО. Масалан, PHONE_NUMBER_OCCUPIED ё FILE_PART_X_MISSING. Хуб, ин аст, ки шумо то ҳол ба ин хат лозим аст таҳлил. Масалан, FLOOD_WAIT_3600 маънои онро дорад, ки шумо бояд як соат интизор, ва PHONE_MIGRATE_5ки рақами телефони дорои ин префикс бояд дар 5 DC ба қайд гирифта шавад. Мо забони типӣ дорем, дуруст? Ба мо далел аз сатр лозим нест, ибораҳои муқаррарӣ кор хоҳанд кард, cho.

Боз ҳам, ин дар саҳифаи паёмҳои хидматӣ нест, аммо, тавре ки аллакай дар ин лоиҳа маъмул аст, маълумотро пайдо кардан мумкин аст. дар саҳифаи дигари ҳуҷҷатҳо. Ё шубҳа ба вуҷуд оварад. Якум, бубинед, вайронкунии чопкунӣ/қабатҳо - RpcError сармоягузорӣ кардан мумкин аст RpcResult. Чаро берун не? Чиро ба назар нагирифтаем?.. Мувофики он, кафолат кучост, ки RpcError сармоягузорӣ кардан мумкин нест RpcResult, балки бевосита ё дар намуди дигар лона? намерасад req_msg_id ? ..

Аммо биёед дар бораи паёмҳои хидматӣ идома диҳем. Муштарӣ метавонад фикр кунад, ки сервер муддати тӯлонӣ фикр мекунад ва чунин дархости олиҷаноб кунад:

rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;

Ба он се ҷавоби эҳтимолӣ вуҷуд дорад, ки боз бо механизми тасдиқ бурида мешавад, то бифаҳмад, ки онҳо чӣ гуна бояд бошанд (ва рӯйхати намудҳое, ки умуман тасдиқро талаб намекунанд) ба хонанда ҳамчун вазифаи хонагӣ гузошта мешаванд (эътибор: маълумот дар манбаҳои Telegram Desktop пурра нест).

Нашъамандӣ: Статусҳои паёмҳо

Умуман, бисёр ҷойҳо дар TL, MTProto ва Telegram умуман эҳсоси якравро тарк мекунанд, аммо аз рӯи хушмуомила, хушмуомила ва ғайра. малакаҳои нармафзор дар ин бора хушмуомила сукут мекардем ва дар муколамахо фашшо цензура карда мешуданд. Бо вуҷуди ин, ин ҷойОқисми зиёди саҳифа дар бораи паёмҳо дар бораи паёмҳо ҳатто барои ман, ки муддати тӯлонӣ бо протоколҳои шабакавӣ кор мекардам ва велосипедҳои дараҷаҳои гуногуни каҷро дидаам, ба ҳайрат меорад.

Он безарар, бо тасдиқҳо оғоз меёбад. Баъд, ба мо дар бораи он гуфта мешавад

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;

Хуб, ҳар касе, ки бо MTProto кор мекунад, бояд бо онҳо рӯ ба рӯ шавад, дар давраи "ислоҳшуда - аз нав тартиб додашуда - оғозшуда" ба даст овардани хатогиҳои рақамӣ ё намак, ки ҳангоми таҳрир пӯсида шудааст, як чизи маъмулист. Аммо, дар ин ҷо ду нукта вуҷуд дорад:

  1. Аз ин бармеояд, ки паёми аслӣ гум шудааст. Мо бояд баъзе навбатҳоро девор кунем, мо инро дертар баррасӣ хоҳем кард.
  2. Ин рақамҳои хатогии аҷиб чист? 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 64... рақамҳои боқимонда дар куҷоянд, Томми?

Дар ҳуҷҷатҳо гуфта мешавад:

Мақсад аз он иборат аст, ки арзишҳои коди хато гурӯҳбандӣ карда мешаванд (рамзи хатои >> 4): масалан, рамзҳои 0x40 - 0x4f ба хатогиҳо дар таҷзияи контейнер мувофиқат мекунанд.

аммо, аввалан, гузаштан ба самти дигар, дуюм, муҳим нест, ки боқимондаи кодҳо дар куҷоянд? Дар сари муаллиф?.. Аммо, инхо майда-чуйдахо.

Нашъамандӣ дар паёмҳои мақоми пост ва нусхаҳои интишор оғоз мешавад:

  • Дархост барои маълумот дар бораи ҳолати паём
    Агар ягон тараф дар муддати муддате дар бораи вазъи паёмҳои содиротии худ маълумот нагирифта бошад, он метавонад онро аз ҷониби дигар ба таври возеҳ талаб кунад:
    msgs_state_req#da69fb52 msg_ids:Vector long = MsgsStateReq;
  • Паёми иттилоотӣ дар бораи ҳолати паёмҳо
    msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;
    Ин ҷо, info сатрест, ки маҳз як байт ҳолати паёмро барои ҳар як паём аз рӯйхати msg_ids воридотӣ дар бар мегирад:

    • 1 = дар бораи паём чизе маълум нест (msg_id хеле паст аст, тарафи дигар онро фаромӯш карда бошад)
    • 2 = паём қабул нашудааст (msg_id ба доираи идентификаторҳои захирашуда рост меояд; аммо тарафи дигар албатта чунин паёмро нагирифтааст)
    • 3 = паём қабул карда нашуд (msg_id хеле баланд; аммо тарафи дигар албатта онро ҳанӯз нагирифтааст)
    • 4 = паём гирифта шуд (дар хотир доред, ки ин посух ҳамзамон тасдиқи квитансия аст)
    • +8 = паём аллакай эътироф шудааст
    • +16 = паёме, ки тасдиқро талаб намекунад
    • +32 = Дархости RPC дар паёме, ки коркард мешавад ё коркард аллакай анҷом ёфтааст
    • +64 = вокуниши марбут ба мундариҷа ба паёми аллакай тавлидшуда
    • +128 = тарафи дигар медонад, ки паём аллакай гирифта шудааст
      Ин ҷавоб эътирофро талаб намекунад. Ин эътирофи msgs_state_req дахлдор аст, дар худ.
      Аҳамият диҳед, ки агар ногаҳон маълум шавад, ки тарафи дигар паёме надорад, ки гӯё ба он фиристода шуда бошад, паёмро метавон танҳо дубора ирсол кард. Ҳатто агар тарафи дигар бояд ду нусхаи паёмро дар як вақт қабул кунад, нусхаи такрорӣ сарфи назар карда мешавад. (Агар вақти аз ҳад зиёд гузашта бошад ва msg_id-и аслӣ дигар эътибор надорад, паём бояд дар msg_copy печонида шавад).
  • Интишори ихтиёрии вазъи паёмҳо
    Ҳар як тараф метавонад ихтиёран ба тарафи дигар дар бораи вазъи паёмҳои ирсолкардаи тарафи дигар хабар диҳад.
    msgs_all_info#8cc0d131 msg_ids:Vector long info:string = MsgsAllInfo
  • Муоширати васеъи ихтиёрии мақоми як паём
    ...
    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;
  • Дархости возеҳ барои аз нав фиристодани паёмҳо
    msg_resend_req#7d861a08 msg_ids:Vector long = MsgResendReq;
    Тарафи дурдаст фавран бо фиристодани паёмҳои дархостшуда ҷавоб медиҳад [...]
  • Дархости возеҳ барои аз нав фиристодани ҷавобҳо
    msg_resend_ans_req#8610baeb msg_ids:Vector long = MsgResendReq;
    Ҳизби дурдаст фавран бо фиристодани дубора ҷавоб медиҳад ҷавоб ба паёмҳои дархостшуда […]
  • Нусхаҳои паёмҳо
    Дар баъзе ҳолатҳо, паёми кӯҳна бо msg_id, ки дигар эътибор надорад, бояд дубора фиристода шавад. Сипас, он дар як контейнери нусхабардорӣ печонида мешавад:
    msg_copy#e06046b2 orig_message:Message = MessageCopy;
    Пас аз қабул, паём кор карда мешавад, ки гӯё бастабандӣ вуҷуд надошта бошад. Аммо, агар маълум бошад, ки паёми orig_message.msg_id гирифта шудааст, пас паёми нав коркард намешавад (дар айни замон он ва orig_message.msg_id эътироф карда мешаванд). Қимати orig_message.msg_id бояд аз msg_id-и контейнер пасттар бошад.

Биёед ҳатто дар бораи он, ки дар msgs_state_info боз, гӯшҳои TL-и нотамом берун мебароянд (ба мо як вектори байт лозим буд ва дар ду битҳои поёнии enum ва дар битҳои кӯҳна парчамҳо). Гап чизи дигар аст. Оё касе мефаҳмад, ки чаро ҳамаи ин дар амал аст дар муштарии воқеӣ лозим аст?.. Бо душворӣ, вале шумо метавонед баъзе фоида тасаввур кунед, агар шахсе, ки бо debugging машғул аст, ва дар як ҳолати интерактивӣ - аз сервер пурсед, ки чӣ ва чӣ тавр. Аммо дархостҳо дар ин ҷо тавсиф карда мешаванд сафари рафту баргашт.

Аз ин бармеояд, ки ҳар як тараф бояд на танҳо паёмҳоро рамзгузорӣ ва ирсол кунад, балки маълумотро дар бораи онҳо, дар бораи ҷавобҳо ба онҳо ва муддати номаълум нигоҳ дорад. Ҳуҷҷатҳо мӯҳлатҳо ё татбиқи амалии ин хусусиятҳоро тавсиф намекунанд. ҳеҷ роҳе нест. Аз ҳама тааҷҷубовар он аст, ки онҳо воқеан дар коди муштариёни расмӣ истифода мешаванд! Аз афташ, ба онхо чизе гуфта шудааст, ки дар хуччатхои кушод дохил нашуда буд. Аз код фаҳмед Чаро?, акнун мисли TL содда нест - ин қисми (муқоисаи) мантиқӣ ҷудошуда нест, балки порчаи ба меъмории барнома вобаста аст, яъне. барои фаҳмидани рамзи барнома вақти зиёдро талаб мекунад.

Пингҳо ва вақтҳо. Навбатҳо.

Аз ҳама чиз, агар шумо тахминҳоро дар бораи меъмории сервер ба ёд оред (тақсимоти дархостҳо дар байни пуштибонҳо), чизи хеле кундзе ба назар мерасад - сарфи назар аз ҳама кафолатҳои интиқол, ки дар TCP (ё маълумот расонида шудааст, ё шумо дар бораи мешикананд, аммо маълумот то лаҳзаи мушкилот расонида мешавад), ки тасдиқҳо дар худи MTProto - кафолат нест. Сервер метавонад паёми шуморо ба осонӣ гум кунад ё партояд ва дар ин бора ҳеҷ кор кардан мумкин нест, танҳо барои девор кардани асобагонҳои намудҳои гуногун.

Ва пеш аз ҳама - навбатҳои паёмҳо. Хуб, барои як чиз, ҳама чиз аз аввал маълум буд - паёми тасдиқнашуда бояд захира карда шавад ва дубора фиристода шавад. Ва баъд аз чанд вақт? Ва шӯхӣ ӯро мешиносад. Эҳтимол, он паёмҳои хидматрасонии нашъаманд ин мушкилотро бо асобағалҳо ҳал кунанд, бигӯед, дар Telegram Desktop тақрибан 4 навбат ба онҳо мувофиқанд (шояд бештар, тавре ки қаблан зикр гардид, барои ин шумо бояд ба код ва меъмории он ҷиддӣ шинос шавед; ҳамзамон вақт, мо медонем, ки онро ҳамчун намуна гирифтан мумкин нест, шумораи муайяни намудҳо аз схемаи MTProto дар он истифода намешаванд).

Чаро ин рӯй медиҳад? Эҳтимол, барномасозони сервер натавонистанд эътимодро дар дохили кластер таъмин кунанд ва ё ҳадди аққал буферӣ дар баланси пештараро таъмин кунанд ва ин мушкилотро ба муштарӣ интиқол доданд. Аз ноумедӣ, Василий кӯшиш кард, ки як варианти алтернативӣ бо ду навбат бо истифода аз алгоритмҳои TCP - андозагирии RTT ба сервер ва танзими андозаи "равзана" (дар паёмҳо) вобаста ба шумораи дархостҳои эътирофнашуда амал кунад. Яъне, чунин эвристикаи ноҳамвор барои ҳисоб кардани сарбории сервер - чӣ қадар дархостҳои мо он метавонад дар як вақт хоидан ва аз даст надиҳад.

Хуб, шумо мефаҳмед, дуруст? Агар шумо бояд TCP-ро дар болои протоколе, ки аз болои TCP кор мекунад, дубора татбиқ кунед, ин протоколи хеле суст тарҳрезишударо нишон медиҳад.

Оре, чаро зиёда аз як навбат лозим аст ва дар маҷмӯъ, ин барои шахсе, ки бо API-и сатҳи баланд кор мекунад, чӣ маъно дорад? Нигоҳ кунед, шумо дархост мекунед, шумо онро серия мекунед, аммо зуд фиристодани он ғайриимкон аст. Чаро? Зеро ҷавоб хоҳад буд msg_id, ки муваккатй астаМан як тамға ҳастам, ки таъини онро ҳарчи дертар ба таъхир андохтан беҳтар аст - ногаҳон сервер онро аз сабаби номутобиқатии вақт байни мо ва он рад мекунад (албатта, мо метавонем асобағе созем, ки вақти моро аз ҳозира иваз кунад. ба вақти сервер бо илова кардани дельта, ки аз посухҳои сервер ҳисоб карда шудааст - муштариёни расмӣ ин корро мекунанд, аммо ин усул аз сабаби буферӣ хом ва нодуруст аст). Ҳамин тавр, вақте ки шумо бо занги функсияи маҳаллӣ аз китобхона дархост мекунед, паём аз марҳилаҳои зерин мегузарад:

  1. Дар як навбат ҷойгир аст ва интизори рамзгузорӣ аст.
  2. таъин шудааст msg_id ва паём ба навбати дигар рафт - интиқоли имконпазир; ба розетка фиристед.
  3. a) Сервер MsgsAck ҷавоб дод - паём расонида шуд, мо онро аз "навбати дигар" нест мекунем.
    б) Ё баръакс, ба ӯ чизе маъқул нашуд, ӯ ҷавоб дод badmsg - мо аз "навбати дигар" дубора мефиристем
    в) Ҳеҷ чиз маълум нест, зарур аст, ки паёмро аз навбати дигар дубора фиристед - аммо кай маълум нест.
  4. Ниҳоят сервер ҷавоб дод RpcResult - вокуниши воқеӣ (ё хато) - на танҳо расонида шуд, балки коркард шудааст.

Эҳтимол, истифода бурдани зарфхо масъаларо кисман хал карда метавонист. Ин вақтест, ки як қатор паёмҳо дар як паём баста мешаванд ва сервер ба ҳама якбора бо як изҳорот ҷавоб дод. msg_id. Аммо ӯ инчунин ин бастаро рад мекунад, агар чизе хато кунад, инчунин ҳама чизро рад мекунад.

Ва дар ин лаҳза, мулоҳизаҳои ғайритехникӣ ба амал меоянд. Мо аз тачриба асо-сабхои зиёдеро дидем ва илова бар ин, акнун бештар мисолхои маслихату меъмории бадро мебинем — дар чунин шароит оё бовар кардан ва кабул кардани чунин карорхо меарзад? Савол риторикист (албатта не).

Мо дар бораи чӣ гап мезанем? Агар дар мавзӯи "паёмҳои нашъамандӣ дар бораи паёмҳо" шумо ҳоло ҳам метавонед бо эътирозҳое мисли "шумо аблаҳ ҳастед, шумо идеяи олиҷаноби моро нафаҳмидаед!" (аз ин рӯ, аввал ҳуҷҷатҳоро, тавре ки одамони оддӣ бояд бо мисолҳои асоснок ва мубодилаи пакетҳо нависед, пас мо сӯҳбат хоҳем кард), пас вақтҳо / вақтҳо як масъалаи комилан амалӣ ва мушаххас мебошанд, ҳама чиз дар ин ҷо кайҳо маълум аст. Аммо ҳуҷҷатҳо ба мо дар бораи мӯҳлатҳо чӣ мегӯянд?

Сервер одатан гирифтани паёмро аз муштарӣ (одатан, дархости RPC) бо истифода аз посухи RPC эътироф мекунад. Агар посух муддати тӯлонӣ омада бошад, сервер метавонад аввал тасдиқи квитансияро фиристад ва каме дертар худи посухи RPC.

Мизоҷ одатан қабули паёмро аз сервер (одатан ҷавоби RPC) бо илова кардани тасдиқ ба дархости навбатии RPC тасдиқ мекунад, агар он хеле дер интиқол наёбад (агар он тавлид шавад, масалан, пас аз 60-120 сония пас аз қабул). паём аз сервер). Аммо, агар дар муддати тӯлонӣ барои фиристодани паёмҳо ба сервер ягон сабаб вуҷуд надошта бошад ё шумораи зиёди паёмҳои эътирофнашуда аз сервер мавҷуд бошад (масалан, зиёда аз 16), муштарӣ тасдиқи мустақилро интиқол медиҳад.

...Ман тарчума мекунам: мо худамон намедонем, ки ин чй кадар ва чй тавр зарур аст, хуб, тахмин кунем, ки ин тавр бошад.

Ва дар бораи пингҳо:

Паёмҳои пинг (PING/PONG)

ping#7abe77ec ping_id:long = Pong;

Ҷавоб одатан ба ҳамон пайваст бармегардад:

pong#347773c5 msg_id:long ping_id:long = Pong;

Ин паёмҳо тасдиқро талаб намекунанд. Понг танҳо дар посух ба пинг интиқол дода мешавад, дар ҳоле ки пингро аз ҳарду ҷониб оғоз кардан мумкин аст.

Батаъхиргузори бастани пайвастшавӣ + PING

ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;

Мисли пинг кор мекунад. Илова бар ин, пас аз қабули ин, сервер вақтсанҷро оғоз мекунад, ки пайвасти ҷории disconnect_delay пас аз сонияҳоро мебандад, агар он паёми нави як навъ нагирад, ки ҳамаи таймерҳои қаблиро ба таври худкор аз нав барқарор кунад. Агар муштарӣ ин пингҳоро дар ҳар 60 сония як маротиба фиристад, масалан, он метавонад disconnect_delay-ро ба 75 сония баробар кунад.

Шумо аз ақл берун шудед?! Пас аз 60 сония поезд ба вокзал даромада, пассажиронро мефурорад ва мебардорад ва боз дар туннель алокаро гум мекунад. Пас аз 120 сония, вақте ки шумо дар гирду атроф шитофтед, ӯ ба дигараш мерасад ва эҳтимоли зиёд пайвастшавӣ қатъ мешавад. Хуб, маълум аст, ки пойҳо аз куҷо мерӯянд - "Ман зангро шунидам, аммо намедонам дар куҷост", алгоритми Nagle ва варианти TCP_NODELAY мавҷуд аст, ки барои кори интерактивӣ пешбинӣ шудааст. Аммо, бубахшед, арзиши пешфарзии онро таъхир кунед - 200 миллисония. Агар шумо воқеан хоҳед, ки як чизи шабеҳро тасвир кунед ва дар як ҷуфти эҳтимолии бастаҳо сарфа кунед - хуб, онро ҳадди аққал 5 сония гузоред, ё новобаста аз он ки вақти фарорасии паёми "Истифодабаранда чоп мекунад ..." ҳоло ба он баробар аст. Аммо дигар не.

Ва ниҳоят, пингҳо. Яъне, тафтиши зинда будани пайвасти TCP. Ин хандаовар аст, аммо тақрибан 10 сол пеш ман дар бораи паёмбари хобгоҳи факултетамон як матни интиқодӣ навишта будам - ​​дар он ҷо муаллифон серверро аз муштарӣ низ пинг карданд, на баръакс. Аммо донишҷӯёни соли сеюм як чиз ва идораи байналмилалӣ дигар аст, дуруст? ..

Якум, як барномаи хурди таълимӣ. Пайвасти TCP, дар сурати набудани мубодилаи бастаҳо, метавонад ҳафтаҳо зиндагӣ кунад. Ин вобаста ба ҳадаф ҳам хуб ва ҳам бад аст. Хуб, агар шумо пайвасти SSH ба сервер кушода будед, шумо аз компютери худ хестаед, роутери барқро бозоғоз кардед, ба ҷои худ баргаштед - сессия тавассути ин сервер вайрон нашуд (ҳеҷ чиз нанавишт, бастаҳо набуд), қулай. Бад аст, агар дар сервер ҳазорҳо муштарӣ бошанд, ҳар яки онҳо захираҳоро истифода мебаранд (салом Postgres!) Ва мизбони муштарӣ шояд кайҳо боз ба кор андохта шуда бошад - аммо мо дар ин бора намедонем.

Системаҳои чат/IM ба ҳолати дуюм тааллуқ доранд, бо сабаби дигаре, ки иловагӣ - мақоми онлайн. Агар корбар "афтида" бошад, дар ин бора ба ҳамсӯҳбатони худ хабар додан лозим аст. Дар акси ҳол, хатое хоҳад буд, ки созандагони Ҷаббер содир кардаанд (ва дар тӯли 20 сол ислоҳ карданд) - корбар аз пайвастшавӣ ҷудо шуд, аммо онҳо ба он бовар мекунанд, ки ӯ онлайн аст (ки дар ин чанд дақиқа пеш аз он низ комилан гум шуда буданд) ба ӯ паём менависанд. танаффус ошкор карда шуд). Не, варианти TCP_KEEPALIVE, ки бисёр одамоне, ки чӣ тавр кор кардани таймерҳои TCP-ро намефаҳманд, дар ҳама ҷо пайдо мешаванд (бо гузоштани арзишҳои ваҳшӣ ба мисли даҳҳо сония), дар ин ҷо кӯмак намекунад - шумо бояд боварӣ ҳосил кунед, ки на танҳо ядрои ОС. мошини корбар зинда аст, аммо инчунин ба таври мӯътадил кор мекунад, дар ҷавоб додан ва худи барнома (ба фикри шумо, он ях карда наметавонад? Мизи кории Telegram дар Ubuntu 18.04 барои ман борҳо садама зад).

Аз ин рӯ, шумо бояд пинг кунед сервер муштарӣ, ва на баръакс - агар муштарӣ ин корро кунад, вақте ки пайвастшавӣ вайрон мешавад, пинг интиқол дода намешавад, ҳадаф ба даст намеояд.

Ва мо дар Telegram чӣ мебинем? Ҳама чиз баръакс аст! Хуб, яъне. ба таври расмй, албатта, хар ду тараф ба хамдигар пинг карда метавонанд. Дар амал мизочон асобачаро истифода мебаранд ping_delay_disconnect, ки таймерро дар сервер мекушояд. Хуб, бубахшед, ин кори муштарӣ нест, ки чӣ қадар вақт мехоҳад дар он ҷо бидуни пинг зиндагӣ кунад. Сервер, дар асоси бори худ, беҳтар медонад. Аммо, албатта, агар шумо ба захираҳо пушаймон нашавед, пас Пиноккиои бад худашон ҳастанд ва асобағлоқа ба замин меафтад ...

Он бояд чӣ гуна тарҳрезӣ мешуд?

Ман боварӣ дорам, ки далелҳои дар боло зикршуда комилан возеҳ нишон медиҳанд, ки салоҳияти на он қадар баланди дастаи Telegram / VKontakte дар соҳаи нақлиёт (ва поёнии) шабакаҳои компютерӣ ва тахассуси пасти онҳо дар масъалаҳои дахлдор.

Чаро он ин қадар мураккаб шуд ва чӣ гуна меъморони Telegram метавонанд эътироз кунанд? Далели он, ки онҳо кӯшиш карданд, ки сессияе созанд, ки пайвасти TCP-ро паси сар кунад, яъне он чизеро, ки мо ҳоло нарасонидем, баъдтар мерасонем. Эҳтимол, онҳо инчунин кӯшиш карданд, ки нақлиёти UDP-ро созанд, гарчанде ки онҳо ба мушкилот дучор шуданд ва онро партофтанд (барои ҳамин ҳуҷҷат холӣ аст - ҳеҷ чиз барои фахр кардан вуҷуд надошт). Аммо аз сабаби набудани фаҳмиши он, ки шабакаҳо дар маҷмӯъ ва махсусан TCP чӣ гуна кор мекунанд, дар куҷо шумо метавонед ба он такя кунед ва дар куҷо шумо бояд онро худатон анҷом диҳед (ва чӣ гуна) ва кӯшиши якҷоя кардани ин бо криптография «як зарбаи ду». паррандагон бо як санг» — чунин кадо-ра баромад.

Чӣ тавр бояд буд? Дар асоси он ки msg_id тамғаи вақт аст, ки барои пешгирии ҳамлаҳои такрорӣ аз ҷиҳати криптографӣ зарур аст, ин хатои замима кардани функсияи мушаххаскунандаи беназир ба он аст. Аз ин рӯ, бидуни ба таври куллӣ тағир додани меъмории ҷорӣ (вақте ки риштаи Навсозӣ ташаккул меёбад, ин мавзӯи API-и сатҳи баланд барои қисми дигари ин силсилаи паёмҳо аст), кас бояд:

  1. Сервере, ки пайвасти TCP-ро бо муштарӣ нигоҳ медорад, масъулиятро ба дӯш мегирад - агар шумо аз розетка хориҷ карда бошед, агар хоҳиш кунед, хатогиро тасдиқ кунед, коркард кунед ё баргардонед, талафот нест. Пас тасдиқ вектори идентификатор нест, балки танҳо "сеq_no охирини гирифташуда" аст - танҳо рақам, ба монанди TCP (ду рақам - секв ва тасдиқи худ). Мо ҳамеша дар ҷаласа ҳастем, ҳамин тавр не?
  2. Тамғаи вақт барои пешгирии ҳамлаҳои такрорӣ ба майдони алоҳида табдил меёбад. Санҷида шуд, аммо ҳеҷ чизи дигар таъсир намерасонад. Кифоя ва uint32 - агар намаки мо ҳадди ақал ҳар ним рӯз тағйир ёбад, мо метавонем 16 битро ба битҳои поёнии қисми бутуни вақти ҷорӣ ҷудо кунем, боқимонда - ба қисми касри як сония (чун ҳоло аст).
  3. Бозгашт msg_id умуман - аз нуқтаи назари фарқ кардани дархостҳо дар пушти сарҳо, аввал, id-и муштарӣ ва дуюм, id-и сессия мавҷуд аст ва онҳоро муттаҳид мекунад. Мувофиқи он, ҳамчун мушаххаскунандаи дархост танҳо як кифоя аст seq_no.

Инчунин беҳтарин вариант нест, тасодуфии пурра метавонад ҳамчун идентификатор хидмат кунад - ин аллакай дар API-и сатҳи баланд ҳангоми фиристодани паём анҷом дода мешавад. Беҳтар мебуд, ки меъмориро аз нисбӣ ба мутлақ дубора табдил диҳед, аммо ин мавзӯъ барои қисми дигар аст, на ин пост.

API?

Та-дам! Ҳамин тавр, бо роҳи пур аз дарду асобағот роҳ тай карда, мо дар ниҳоят тавонистем ҳама гуна дархостҳоро ба сервер ирсол кунем ва ба онҳо ҷавоб гирем ва инчунин аз сервер навсозиҳо гирем (на дар посух ба дархост, балки он ба мо худ мефиристад, ба монанди PUSH, агар касе ин қадар равшантар).

Диққат, ҳоло дар мақола ягона мисоли Perl хоҳад буд! (барои онҳое, ки бо синтаксис ошно нестанд, далели аввал барои баракат сохтори додаҳои объект аст, дуюм синфи он аст):

2019.10.24 12:00:51 $1 = {
'cb' => 'TeleUpd::__ANON__',
'out' => bless( {
'filter' => bless( {}, 'Telegram::ChannelMessagesFilterEmpty' ),
'channel' => bless( {
'access_hash' => '-6698103710539760874',
'channel_id' => '1380524958'
}, 'Telegram::InputPeerChannel' ),
'pts' => '158503',
'flags' => 0,
'limit' => 0
}, 'Telegram::Updates::GetChannelDifference' ),
'req_id' => '6751291954012037292'
};
2019.10.24 12:00:51 $1 = {
'in' => bless( {
'req_msg_id' => '6751291954012037292',
'result' => bless( {
'pts' => 158508,
'flags' => 3,
'final' => 1,
'new_messages' => [],
'users' => [],
'chats' => [
bless( {
'title' => 'Хулиномика',
'username' => 'hoolinomics',
'flags' => 8288,
'id' => 1380524958,
'access_hash' => '-6698103710539760874',
'broadcast' => 1,
'version' => 0,
'photo' => bless( {
'photo_small' => bless( {
'volume_id' => 246933270,
'file_reference' => '
'secret' => '1854156056801727328',
'local_id' => 228648,
'dc_id' => 2
}, 'Telegram::FileLocation' ),
'photo_big' => bless( {
'dc_id' => 2,
'local_id' => 228650,
'file_reference' => '
'secret' => '1275570353387113110',
'volume_id' => 246933270
}, 'Telegram::FileLocation' )
}, 'Telegram::ChatPhoto' ),
'date' => 1531221081
}, 'Telegram::Channel' )
],
'timeout' => 300,
'other_updates' => [
bless( {
'pts_count' => 0,
'message' => bless( {
'post' => 1,
'id' => 852,
'flags' => 50368,
'views' => 8013,
'entities' => [
bless( {
'length' => 20,
'offset' => 0
}, 'Telegram::MessageEntityBold' ),
bless( {
'length' => 18,
'offset' => 480,
'url' => 'https://alexeymarkov.livejournal.com/[url_вырезан].html'
}, 'Telegram::MessageEntityTextUrl' )
],
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'text' => '???? 165',
'data' => 'send_reaction_0'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'data' => 'send_reaction_1',
'text' => '???? 9'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'message' => 'А вот и новая книга! 
// [текст сообщения вырезан чтоб не нарушать правил Хабра о рекламе]
напечатаю.',
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'date' => 1571724559,
'edit_date' => 1571907562
}, 'Telegram::Message' ),
'pts' => 158508
}, 'Telegram::UpdateEditChannelMessage' ),
bless( {
'pts' => 158508,
'message' => bless( {
'edit_date' => 1571907589,
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'date' => 1571807301,
'message' => 'Почему Вы считаете Facebook плохой компанией? Можете прокомментировать? По-моему, это шикарная компания. Без долгов, с хорошей прибылью, а если решат дивы платить, то и еще могут нехило подорожать.
Для меня ответ совершенно очевиден: потому что Facebook делает ужасный по качеству продукт. Да, у него монопольное положение и да, им пользуется огромное количество людей. Но мир не стоит на месте. Когда-то владельцам Нокии было смешно от первого Айфона. Они думали, что лучше Нокии ничего быть не может и она навсегда останется самым удобным, красивым и твёрдым телефоном - и доля рынка это красноречиво демонстрировала. Теперь им не смешно.
Конечно, рептилоиды сопротивляются напору молодых гениев: так Цукербергом был пожран Whatsapp, потом Instagram. Но всё им не пожрать, Паша Дуров не продаётся!
Так будет и с Фейсбуком. Нельзя всё время делать говно. Кто-то когда-то сделает хороший продукт, куда всё и уйдут.
#соцсети #facebook #акции #рептилоиды',
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'data' => 'send_reaction_0',
'text' => '???? 452'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'text' => '???? 21',
'data' => 'send_reaction_1'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'entities' => [
bless( {
'length' => 199,
'offset' => 0
}, 'Telegram::MessageEntityBold' ),
bless( {
'length' => 8,
'offset' => 919
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'offset' => 928,
'length' => 9
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'length' => 6,
'offset' => 938
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'length' => 11,
'offset' => 945
}, 'Telegram::MessageEntityHashtag' )
],
'views' => 6964,
'flags' => 50368,
'id' => 854,
'post' => 1
}, 'Telegram::Message' ),
'pts_count' => 0
}, 'Telegram::UpdateEditChannelMessage' ),
bless( {
'message' => bless( {
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'data' => 'send_reaction_0',
'text' => '???? 213'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'data' => 'send_reaction_1',
'text' => '???? 8'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'views' => 2940,
'entities' => [
bless( {
'length' => 609,
'offset' => 348
}, 'Telegram::MessageEntityItalic' )
],
'flags' => 50368,
'post' => 1,
'id' => 857,
'edit_date' => 1571907636,
'date' => 1571902479,
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'message' => 'Пост про 1С вызвал бурную полемику. Человек 10 (видимо, 1с-программистов) единодушно написали:
// [текст сообщения вырезан чтоб не нарушать правил Хабра о рекламе]
Я бы добавил, что блестящая у 1С дистрибуция, а маркетинг... ну, такое.'
}, 'Telegram::Message' ),
'pts_count' => 0,
'pts' => 158508
}, 'Telegram::UpdateEditChannelMessage' ),
bless( {
'pts' => 158508,
'pts_count' => 0,
'message' => bless( {
'message' => 'Здравствуйте, расскажите, пожалуйста, чем вредит экономике 1С?
// [текст сообщения вырезан чтоб не нарушать правил Хабра о рекламе]
#софт #it #экономика',
'edit_date' => 1571907650,
'date' => 1571893707,
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'flags' => 50368,
'post' => 1,
'id' => 856,
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'data' => 'send_reaction_0',
'text' => '???? 360'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'data' => 'send_reaction_1',
'text' => '???? 32'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'views' => 4416,
'entities' => [
bless( {
'offset' => 0,
'length' => 64
}, 'Telegram::MessageEntityBold' ),
bless( {
'offset' => 1551,
'length' => 5
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'length' => 3,
'offset' => 1557
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'offset' => 1561,
'length' => 10
}, 'Telegram::MessageEntityHashtag' )
]
}, 'Telegram::Message' )
}, 'Telegram::UpdateEditChannelMessage' )
]
}, 'Telegram::Updates::ChannelDifference' )
}, 'MTProto::RpcResult' )
};
2019.10.24 12:00:51 $1 = {
'in' => bless( {
'update' => bless( {
'user_id' => 2507460,
'status' => bless( {
'was_online' => 1571907651
}, 'Telegram::UserStatusOffline' )
}, 'Telegram::UpdateUserStatus' ),
'date' => 1571907650
}, 'Telegram::UpdateShort' )
};
2019.10.24 12:05:46 $1 = {
'in' => bless( {
'chats' => [],
'date' => 1571907946,
'seq' => 0,
'updates' => [
bless( {
'max_id' => 141719,
'channel_id' => 1295963795
}, 'Telegram::UpdateReadChannelInbox' )
],
'users' => []
}, 'Telegram::Updates' )
};
2019.10.24 13:01:23 $1 = {
'in' => bless( {
'server_salt' => '4914425622822907323',
'unique_id' => '5297282355827493819',
'first_msg_id' => '6751307555044380692'
}, 'MTProto::NewSessionCreated' )
};
2019.10.24 13:24:21 $1 = {
'in' => bless( {
'chats' => [
bless( {
'username' => 'freebsd_ru',
'version' => 0,
'flags' => 5440,
'title' => 'freebsd_ru',
'min' => 1,
'photo' => bless( {
'photo_small' => bless( {
'local_id' => 328733,
'volume_id' => 235140688,
'dc_id' => 2,
'file_reference' => '
'secret' => '4426006807282303416'
}, 'Telegram::FileLocation' ),
'photo_big' => bless( {
'dc_id' => 2,
'file_reference' => '
'volume_id' => 235140688,
'local_id' => 328735,
'secret' => '71251192991540083'
}, 'Telegram::FileLocation' )
}, 'Telegram::ChatPhoto' ),
'date' => 1461248502,
'id' => 1038300508,
'democracy' => 1,
'megagroup' => 1
}, 'Telegram::Channel' )
],
'users' => [
bless( {
'last_name' => 'Panov',
'flags' => 1048646,
'min' => 1,
'id' => 82234609,
'status' => bless( {}, 'Telegram::UserStatusRecently' ),
'first_name' => 'Dima'
}, 'Telegram::User' )
],
'seq' => 0,
'date' => 1571912647,
'updates' => [
bless( {
'pts' => 137596,
'message' => bless( {
'flags' => 256,
'message' => 'Создать джейл с именем покороче ??',
'to_id' => bless( {
'channel_id' => 1038300508
}, 'Telegram::PeerChannel' ),
'id' => 119634,
'date' => 1571912647,
'from_id' => 82234609
}, 'Telegram::Message' ),
'pts_count' => 1
}, 'Telegram::UpdateNewChannelMessage' )
]
}, 'Telegram::Updates' )
};

Бале, махсусан дар зери спойлер нест - агар шумо онро нахонда бошед, рафта ин корро кунед!

Оҳ, вой~~… он чӣ гуна аст? Чизи хеле шинос… шояд ин сохтори додаҳои маъмулии Web API дар JSON бошад, ба истиснои шояд синфҳо ба объектҳо замима шуда бошанд?..

Пас маълум мешавад... Ин чист, рафикон?.. Ин кадар саъю кушиш — ва дар он чое, ки веб-барномасозон дам гирифта буданд, истодем. нав оғоз?.. Оё танҳо JSON бар HTTPS осонтар нест?! Ва мо ба ивази он чӣ гирифтем? Оё ин саъю кӯшишҳо арзанда буданд?

Биёед арзёбӣ кунем, ки TL+MTProto ба мо чӣ дод ва кадом алтернативаҳо имконпазиранд. Хуб, HTTP дархост-ҷавоб мувофиқи бад аст, аммо ҳадди аққал чизе дар болои TLS?

сериализатсияи паймон. Бо дидани ин сохтори додаҳо, ки ба JSON монанд аст, дар хотир доред, ки вариантҳои бинарии он мавҷуданд. Биёед MsgPack-ро ҳамчун нокифоя васеъшаванда қайд кунем, аммо, масалан, CBOR вуҷуд дорад - дар омади гап, стандарте, ки дар RFC 7049. Муайян кардани он чолиби диккат аст барчаспҳо, ҳамчун механизми васеъ ва дар байни аллакай стандартизатсия шудааст ҳастанд:

  • 25 + 256 - иваз кардани сатрҳои такрорӣ бо истинод ба рақами сатр, чунин усули фишурдасозии арзон
  • 26 - объекти силсилавии Perl бо номи синф ва аргументҳои созанда
  • 27 - объекти мустақили забон бо номи намуд ва аргументҳои созанда сериализатсияшуда

Хуб, ман кӯшиш кардам, ки ҳамон маълумотро дар TL ва CBOR бо бастабандии сатрҳо ва объектҳо фаъол созам. Натиҷа ба фоидаи CBOR дар ҷое аз мегабайт фарқ мекард:

cborlen=1039673 tl_len=1095092

Ва ҳамин тавр, хулоса: Форматҳои хеле соддатаре мавҷуданд, ки ба нокомии синхронизатсия ё мушкилоти идентификатори номаълум бо самаранокии муқоисашаванда дучор намешаванд.

Таъсиси пайвасти зуд. Ин маънои онро дорад, ки сифр RTT пас аз пайвастшавӣ (вақте ки калид аллакай як бор тавлид шудааст) - аз паёми аввалини MTProto татбиқ мешавад, аммо бо баъзе қайдҳо - онҳо ба ҳамон намак даромаданд, сессия пӯсида нашуд ва ғайра. TLS дар иваз ба мо чӣ пешниҳод мекунад? Иқтибосҳои марбут:

Ҳангоми истифодаи PFS дар TLS, чиптаҳои сессияи TLS (RFC 5077) барои идома додани сеанси рамзгузоришуда бидуни баррасии калидҳо ва бидуни нигоҳ доштани маълумоти калидӣ дар сервер. Ҳангоми кушодани пайвасти аввал ва тавлиди калидҳо сервер ҳолати пайвастшавиро рамзкунонида, онро ба муштарӣ мефиристад (дар шакли чиптаи сессия). Мутаносибан, вақте ки пайвастшавӣ барқарор карда мешавад, муштарӣ чиптаи сессияро, ки аз ҷумла калиди сессияро дар бар мегирад, ба сервер мефиристад. Худи чипта бо калиди муваққатӣ (калиди чиптаи сеанс) рамзгузорӣ шудааст, ки дар сервер нигоҳ дошта мешавад ва бояд ба ҳама серверҳои фронтенд, ки SSL-ро дар ҳалли кластерӣ идора мекунанд, тақсим карда шавад.[10]. Ҳамин тариқ, ҷорӣ намудани чиптаи сеанс метавонад PFS-ро вайрон кунад, агар калидҳои сервери муваққатӣ халалдор шаванд, масалан, вақте ки онҳо барои муддати тӯлонӣ нигоҳ дошта мешаванд (OpenSSL, nginx, Apache ба таври нобаёнӣ онҳоро дар давоми тамоми вақти иҷрошавии барнома нигоҳ медоранд; сайтҳои маъмул калидро барои якчанд соат, то рӯзҳо истифода баред).

Дар ин ҷо RTT сифр нест, шумо бояд ҳадди аққал ClientHello ва ServerHello-ро мубодила кунед, ки пас аз он дар якҷоягӣ бо Finished муштарӣ аллакай маълумот фиристад. Аммо дар ин ҷо бояд дар хотир дошт, ки мо веб надорем, ки бо як қатор пайвастагиҳои нав кушодашуда, балки паёмбаре дорем, ки пайвасти он аксар вақт як ва ё камтар умри дароз, дархостҳои нисбатан кӯтоҳ барои саҳифаҳои веб - ҳама чиз аст. дар дохили мултиплекс. Яъне, ин комилан қобили қабул аст, агар мо ба қисмати хеле бад дар метро дучор нашавем.

Чизи дигареро фаромӯш кардед? Дар шарҳҳо нависед.

Давом дорад!

Дар қисми дуюми ин силсилаи мақолаҳо мо на масъалаҳои техникӣ, балки масъалаҳои ташкилиро баррасӣ хоҳем кард - равишҳо, идеология, интерфейс, муносибат ба корбарон ва ғайра. Бо вуҷуди ин, дар асоси маълумоти техникӣ, ки дар ин ҷо оварда шудааст.

Қисми сеюм таҳлили ҷузъи техникӣ / таҷрибаи рушдро идома медиҳад. Шумо махсусан меомӯзед:

  • давом додани пандемонй бо навъхои гуногуни ТЛ
  • чизҳои номаълум дар бораи каналҳо ва супергурӯҳҳо
  • аз муколамаҳо аз рӯйхат бадтар аст
  • дар бораи адресатсияи мутлақ ва нисбии паём
  • Фарқи байни акс ва тасвир чӣ гуна аст
  • чӣ гуна эмодзиҳо ба матни курсив халал мерасонанд

ва дигар асобагон! Гӯш ба занг бош!

Манбаъ: will.com

Илова Эзоҳ