د ټیلیګرام پروتوکول او تنظیمي چلندونو انتقاد. برخه 1، تخنیکي: له سکریچ څخه د پیرودونکي لیکلو تجربه - TL, MT

پدې وروستیو کې ، پوسټونه په هابري کې ډیر ځله څرګندیدل پیل شوي چې ټیلیګرام څومره ښه دی ، د ډیروف وروڼه د شبکې سیسټمونو رامینځته کولو کې څومره تکړه او تجربه لرونکي دي ، او داسې نور. په ورته وخت کې ، ډیر لږ خلک واقعیا په تخنیکي وسیله کې ډوب شوي - ډیری یې د کافي ساده (او د MTProto څخه خورا مختلف) JSON-based Bot API کاروي ، او معمولا یوازې مني. په ایمان ټول هغه ستاینې او PR چې د رسول شاوخوا ګرځي. نږدې یو نیم کال دمخه ، په NPO Echelon Vasily کې زما همکار (له بده مرغه ، په هابر کې د هغه حساب د مسودې سره حذف شوی و) په پرل کې له سکریچ څخه د خپل ټیلیګرام پیرودونکي لیکل پیل کړل ، او وروسته د دې لینونو لیکوال یوځای شو. ولې پرل، ځینې به سمدستي پوښتنه وکړي؟ ځکه په نورو ژبو کې دا ډول پروژې لا دمخه شته، په حقیقت کې دا خبره نه ده، کېدای شي بله ژبه پکې وي بشپړ شوی کتابتون، او په دې اساس لیکوال باید په ټوله لاره لاړ شي له شروع څخه. سربیره پردې، کریپټوګرافي یو داسې شی دی - باور، مګر تصدیق. د امنیت متمرکز محصول سره ، تاسو نشئ کولی یوازې د پلورونکي چمتو شوي کتابتون باندې تکیه وکړئ او په ړوند ډول باور وکړئ (په هرصورت ، دا په دویمه برخه کې د نورو لپاره موضوع ده). اوس مهال، کتابتون په "منځنۍ" کچه خورا ښه کار کوي (تاسو ته اجازه درکوي چې د API غوښتنې وکړئ).

په هرصورت، د پوستونو په دې لړۍ کې به ډیر کریپټوګرافي او ریاضي نه وي. مګر ډیری نور تخنیکي توضیحات او معماري کرچچونه به وي (دا به د هغو کسانو لپاره هم ګټور وي څوک چې له سکریچ څخه نه لیکي ، مګر کتابتون به په هره ژبه کې کاروي). نو، اصلي موخه دا وه چې د پیرودونکي څخه د پیل څخه پلي کولو هڅه وکړي د رسمي اسنادو له مخې. دا دی، فرض کړئ چې د رسمي مراجعینو د سرچینې کوډ تړل شوی دی (بیا، په دویمه برخه کې، موږ به په تفصیل سره د موضوع موضوع په ډاګه کړو چې دا واقعیا څه دي. دا پیښیږي نو)، مګر، لکه څنګه چې په پخوانیو ورځو کې، د بیلګې په توګه، د RFC په څیر یو معیار شتون لري - ایا دا ممکنه ده چې یو پیرودونکي یوازې د ځانګړتیاوو سره سم، د سرچینې کوډ ته "پرته له کتلو پرته" ولیکئ، حتی رسمي (د ټیلیګرام ډیسټاپ، موبایل )، حتی غیر رسمي ټیلیون؟

فهرست:

اسناد ... شته؟ آیا دا سمه ده؟..

د دې مقالې لپاره د نوټونو ټوټې تیر اوړي راټولول پیل کړل. دا ټول وخت په رسمي سایټ کې https://core.telegram.org اسناد د 23 پرت پورې وو، i.e. په 2014 کې یو ځای ودرول شو (په یاد ولرئ، هغه وخت حتی چینلونه هم نه وو؟). البته، په تیوري کې، دا باید په 2014 کې په هغه وخت کې د فعالیت سره د پیرودونکي پلي کول ممکن کړي. خو حتی په دې حالت کې، اسناد لومړی، نیمګړتیا، او دویم، په ځینو ځایونو کې دا پخپله مخالفت کوي. یوه میاشت دمخه، د سپتمبر په 2019 کې، دا وه په ناڅاپه توګه دا وموندل شوه چې سایټ د اسنادو لوی تازه معلومات لري، د بشپړ تازه پرت 105 لپاره، د یادښت سره چې اوس هرڅه بیا لوستلو ته اړتیا لري. په حقیقت کې، ډیری مقالې تعدیل شوي، مګر ډیری یې پاتې دي. له همدې امله، کله چې د اسنادو په اړه لاندې نیوکې ولولئ، تاسو باید په پام کې ونیسئ چې ځینې دا شیان نور اړوند ندي، مګر ځینې یې لاهم کافي دي. په هرصورت، په عصري نړۍ کې 5 کاله یوازې ډیر نه دي، مګر ډېر بیخي ډېر. له هغه وخت راهیسې (په ځانګړي توګه که تاسو له هغه وخت راهیسې رد شوي او بیا راژوندي شوي جیوچیټونه په پام کې نه ونیسئ) ، په سکیم کې د API میتودونو شمیر له سلو څخه دوه سوه او پنځوسو ته لوړ شوی!

تاسو د یو ځوان لیکوال په توګه چیرته پیل کوئ؟

دا مهمه نده چې تاسو له سکریچ څخه ولیکئ یا کاروئ، د بیلګې په توګه، چمتو شوي کتابتونونه د Python لپاره ټیلیون او یا د PHP لپاره میډیلینپه هر حالت کې، تاسو به لومړی اړتیا ولرئ خپل غوښتنلیک ثبت کړئ - پیرامیټونه ترلاسه کړئ api_id и api_hash (هغه څوک چې د VKontakte API سره کار کوي سمدلاسه پوهیږي) د کوم په واسطه چې سرور به غوښتنلیک وپیژني. دا باید ولري د قانوني دلایلو لپاره، مګر موږ به په دې اړه نور خبرې وکړو چې ولې د کتابتون لیکوالان نشي کولی په دویمه برخه کې خپاره کړي. شاید تاسو به د ازموینې ارزښتونو څخه راضي شئ، که څه هم دوی خورا محدود دي - حقیقت دا دی چې اوس تاسو کولی شئ په خپل شمیر کې راجستر شئ یوازې یو غوښتنلیک، نو په سر کې بېړه مه کوئ.

اوس، د تخنیکي نظر څخه، موږ باید د دې حقیقت سره علاقه درلوده چې د راجستریشن وروسته موږ باید د اسنادو، پروتوکول او نورو تازه معلوماتو په اړه د ټیلیګرام څخه خبرتیا ترلاسه کړو. دا دی، یو څوک فرض کولی شي چې د ډاکونو سره سایټ په ساده ډول "سکور شوی" و او په ځانګړې توګه د هغو کسانو سره کار کولو ته دوام ورکوي چې پیرودونکي یې پیل کړي، ځکه چې. دا اسانه ده. مګر نه، داسې څه نه لیدل شوي، هیڅ معلومات نه دي راغلي.

او که تاسو له سکریچ څخه ولیکئ ، نو د ترلاسه شوي پیرامیټونو کارول واقعیا لاهم خورا لرې دي. که څه هم https://core.telegram.org/ او د دوی په اړه لومړی په پیل کولو کې خبرې کوي، په حقیقت کې، تاسو باید لومړی پلي کړئ د MTProto پروتوکول - مګر که تاسو باور لرئ ترتیب د OSI ماډل سره سم د پروتوکول د عمومي توضیح د پاڼې په پای کې، بیا په بشپړه توګه بې ګټې.

په حقیقت کې ، دواړه د MTProto څخه دمخه او وروسته ، په یوځل کې په څو کچو کې (لکه څنګه چې بهرني شبکې کارونکي په OS کرنل کې کار کوي ، د پرت سرغړونه) ، یو لوی ، دردناک او ویرونکی موضوع به په لاره کې راشي ...

بائنري سریال کول: TL (ډول ژبه) او د هغې سکیم، او پرتونه، او ډیری نور ډارونکي کلمې

دا موضوع، په حقیقت کې، د 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 نسخه کې د سکیما سره نږدې اړیکې شتون لري - مګر دا دا روښانه نه کوي).

د پاڼې پرانیستل د بائنری ډیټا سریال کول او د مرغانو او جلا ریاضياتو جادو نړۍ کې ډوب شئ، په څلورم کال کې متان ته ورته یو څه. الفبا، ډول، ارزښت، ترکیب کوونکی، فعلي ترکیب، نورمال بڼه، جامع ډول، پولیمورفیک ډول ... او دا یوازې لومړی پاڼه ده! بل ستاسو په تمه د TL ژبه، کوم چې ، که څه هم دا دمخه د یوې کوچنۍ غوښتنې او ځواب مثال لري ، په بشپړ ډول نورو عامو قضیو ته ځواب نه ورکوي ، پدې معنی چې تاسو باید په اتو نورو ځنځیرونو کې له روسی څخه انګلیسي ته ژباړل شوي ریاضیاتو له سره تکرار کړئ. پاڼې!

هغه لوستونکي چې د فعالو ژبو او اتوماتیک ډولونو سره آشنا دي، البته، د دې ژبې توضیحات لیدلي، حتی د مثال څخه، خورا ډیر پیژندل شوي، او ویلای شي چې دا عموما په اصولو کې خراب ندی. په دې اړه اعتراضونه دا دي:

  • هو، هدف ښه غږ کوي، مګر افسوس نه دی ترلاسه شوی
  • د روسیې په پوهنتونونو کې زده کړه حتی د معلوماتي ټکنالوجۍ ځانګړتیاو کې توپیر لري - هرڅوک ورته کورس نه لولي
  • په پای کې، لکه څنګه چې موږ به وګورو، په عمل کې دا دی اړتیا نشته، ځکه چې یوازې د حتی د TL محدود فرعي سیټ چې تشریح شوی کارول شوی

لکه څنګه چې ویل شوي لیونیرډ په کانال کې #perl په FreeNode IRC شبکه کې، هڅه کوي د ټیلیګرام څخه میټریکس ته دروازه پلي کړي (د اقتباس ژباړه د حافظې څخه ناسمه ده):

داسې احساس کوي لکه یو څوک چې د لومړي ځل لپاره د تیوري ټایپ کولو ته معرفي شوی و، په زړه پورې شو او د هغې سره یې د لوبې کولو هڅه پیل کړه، واقعیا پروا نه کوي که چیرې دا په عمل کې اړین وي.

د خپل ځان لپاره وګورئ که چیرې د ابتدايي شیانو په توګه د خلاص ډولونو (int، اوږد، او نور) اړتیا پوښتنې نه راپورته کوي - په پای کې دوی باید په لاسي ډول پلي شي - د مثال په توګه، راځئ چې د دوی څخه د اخیستلو هڅه وکړو. ویکتور. دا په حقیقت کې، صف، که تاسو پایله لرونکي شیان د دوی په مناسبو نومونو ووایاست.

خو مخکې

د هغو کسانو لپاره د 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---، او دا جوړونکی به په پام کې ونه نیول شي. د دوی د دلیلونو په واسطه د ویل شوي فنکشنونو ډیر بار ټایپ کړئ، د بیلګې په توګه. د ځینو دلیلونو لپاره، د ورته نوم سره ډیری دندې مګر مختلف لاسلیک، لکه په C++ کې، په TL کې ندي چمتو شوي.

ولې "جوړونکی" او "پولیمورفیک" که دا OOP نه وي؟ ښه، په حقیقت کې، دا به د یو چا لپاره اسانه وي چې د OOP په شرایطو کې د هغې په اړه فکر وکړي - یو پولیمورفیک ډول د خلاصې ټولګي په توګه، او جوړونکي د دې مستقیم نسل ټولګي دي. final د یو شمیر ژبو په اصطلاحاتو کې. په حقیقت کې، البته، دلته ورته والی د OO پروګرامینګ ژبو کې د ریښتیني اوورلوډ جوړونکي میتودونو سره. څنګه چې دلته یوازې د ډیټا جوړښتونه شتون لري ، هیڅ میتودونه شتون نلري (که څه هم لاندې د دندو او میتودونو توضیحات د دې وړتیا لري چې په سر کې ګډوډي رامینځته کړي چې دوی څه دي ، مګر دا د بل څه په اړه دي) - تاسو کولی شئ د یو جوړونکي په اړه فکر وکړئ لکه څنګه چې ارزښت له کوم څخه جوړیږي ټایپ کړئ کله چې د بایټ جریان لوستل کیږي.

دا څنګه کیږي؟ deserializer، چې تل 4 بایټ لوستل کیږي، ارزښت ګوري 0xcrc32 - او پوهیږي چې وروسته به څه پیښ شي field1 ډول سره int، i.e. دقیقا 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معنی "طبیعي شمیره". دا په حقیقت کې، نه لاسلیک شوی int یوازینۍ قضیه ده، په لاره کې، کله چې غیر لاسلیک شوي شمیرې په ریښتینې سرکیټونو کې وموندل شي. نو، راتلونکی د پوښتنې نښه سره یو ساختمان دی، پدې معنی چې دا ساحه ده - دا به یوازې په تار کې شتون ولري که اړونده بټ په حواله شوي ساحه کې تنظیم شوی وي (تقریبا د ټرني آپریټر په څیر). نو ، فرض کړئ چې دا بټ روان و ، نو تاسو اړتیا لرئ د ساحې په څیر ولولئ Type، کوم چې زموږ په مثال کې 2 جوړونکي لري. یو خالي دی (یوازې د پیژندونکي څخه جوړ دی)، بل یې ساحه لري ids ډول سره ids:Vector<long>.

تاسو شاید فکر وکړئ چې دواړه ټیمپلیټونه او جنریک ښه دي یا جاوا. مګر نه. تقریبا. دا یوازینی په ریښتیني سرکیټونو کې د زاویې قوسونو قضیه، او دا یوازې د ویکتور لپاره کارول کیږي. په یوه بایټ جریان کې، دا به د ویکتور ډول لپاره 4 CRC32 بایټونه وي، تل ورته وي، بیا 4 بایټونه - د صف عناصرو شمیر، او بیا دا عناصر پخپله.

دا حقیقت اضافه کړئ چې سیریل کول تل د 4 بایټ کلمو کې پیښیږي ، ټول ډولونه یې ضرب دي - جوړ شوي ډولونه هم بیان شوي. bytes и string د اوږدوالي د لاسي سریال کولو سره او د 4 لخوا دا ترتیب - ښه، داسې ښکاري چې نورمال او حتی نسبتا اغیزمن ښکاري؟ که څه هم TL د اغیزمن بائنری سیریل کولو ادعا کوي، مګر د دوی سره دوزخ ته، د هر څه پراخولو سره، حتی د بولین ارزښتونو او واحد کرکټر تارونه تر 4 بایټ پورې، ایا JSON به لاهم ډیر موټی وي؟ وګورئ، حتی غیر ضروري ساحې د بټ بیرغونو لخوا پریښودل کیدی شي، هرڅه سم دي، او حتی د راتلونکي لپاره د توزیع وړ دي، ایا تاسو وروسته جوړونکي ته نوي اختیاري ساحې اضافه کړې؟ ..

مګر نه، که تاسو زما لنډ توضیحات نه ولولئ، مګر بشپړ اسناد، او د پلي کولو په اړه فکر وکړئ. لومړی، د جوړونکي CRC32 د نورمال شوي سکیما متن توضیحي سټینګ لخوا محاسبه کیږي (اضافي سپین ځای لرې کړئ ، او داسې نور) - نو که چیرې نوې ساحه اضافه شي نو د توضیحاتو ډول به بدل شي ، او له همدې امله د دې CRC32 او په پایله کې سریالیزیشن. او زوړ پیرودونکی به څه وکړي که چیرې هغه د نوي بیرغونو سره ساحه ترلاسه کړي ، مګر هغه نه پوهیږي چې له دوی سره به څه وکړي؟ ..

دوهم، راځئ چې په یاد ولرو CRC32، کوم چې دلته په لازمي ډول کارول کیږي د hash افعال په ځانګړې توګه معلومه کړي چې کوم ډول (de) سریال شوی دی. دلته موږ د ټکرونو ستونزې سره مخ یو - او نه، احتمال په 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 لیږدوي؟

دا په بشپړ ډول بې کاره نظري پوښتنه نه ده - تصور وکړئ چې تاسو د ګروپ کاروونکو لیست ترلاسه کوئ، چې هر یو یې id، لومړی نوم، وروستی نوم لري - د ګرځنده اتصال له لارې لیږدول شوي ډیټا مقدار کې توپیر د پام وړ کیدی شي. دا د ټیلیګرام سیریل کولو تاثیر دی چې موږ ته اعلان کیږي.

نو…

ویکټور، کوم چې نشي اخیستل کیدی

که تاسو هڅه وکړئ چې د ترکیبونو او په اړه د توضیحي پاڼو له لارې وګرځئ، تاسو به وګورئ چې یو ویکتور (او حتی یو میټریکس) په رسمي توګه هڅه کوي څو څو شیټونه د ټپلونو له لارې کم کړي. مګر په پای کې دوی مینځل کیږي، وروستی ګام پریښودل کیږي، او د ویکتور تعریف په ساده ډول ورکړل شوی، کوم چې په یو ډول پورې تړلی نه دی. دلته څه خبره ده؟ په ژبو برنامه کول، په ځانګړي توګه فعاله ، دا خورا معمول دی چې جوړښت په تکراري ډول تشریح کړئ - د دې سست ارزونې سره تالیف کونکی به هرڅه درک کړي او دا به وکړي. په ژبه د معلوماتو لړۍ کول مګر موثریت ته اړتیا ده: دا په ساده ډول تشریح کول کافي دي لست, i.e. د دوه عناصرو جوړښت - لومړی د ډیټا عنصر دی، دوهم پخپله ورته جوړښت دی یا د لکۍ لپاره خالي ځای دی (پیک (cons) په Lisp). مګر دا به په ښکاره ډول اړتیا ولري هر یو عنصر د دې ډول تشریح کولو لپاره 4 بایټونه (CRC32 د TL په حالت کې) مصرفوي. د صف تشریح کول اسانه دي ثابت اندازه، مګر د مخکینۍ نامعلوم اوږدوالي د لړۍ په حالت کې ، موږ مات کوو.

نو ځکه چې TL تاسو ته اجازه نه ورکوي چې ویکتور تولید کړئ، دا باید په اړخ کې اضافه شي. په نهایت کې اسناد وايي:

سیریلائزیشن تل ورته جوړونکی "ویکٹر" کاروي (const 0x1cb5c415 = crc32("vector t:Type # [ t ] = Vector t") چې د t ډول متغیر په ځانګړي ارزښت پورې اړه نلري.

د اختیاري پیرامیټر t ارزښت په سیریل کولو کې دخیل نه دی ځکه چې دا د پایلې ډول څخه اخیستل شوی (تل د سیریل کولو دمخه پیژندل شوی).

نږدې وګورئ: vector {t:Type} # [ t ] = Vector t - مګر هیڅ ځای نه تعریف پخپله دا نه وايي چې لومړۍ شمیره باید د ویکتور اوږدوالي سره مساوي وي! او دا د هر ځای څخه پیروي نه کوي. دا یو ورکړل شوی چې تاسو اړتیا لرئ په ذهن کې وساتئ او د خپلو لاسونو سره پلي کړئ. په بل ځای کې، اسناد حتی په صادقانه توګه یادونه کوي چې ډول جعلي دی:

د ویکتور t پولیمورفیک سیډوټایپ یو "ډول" دی چې ارزښت یې د هر ډول T ارزښتونو ترتیب دی، یا هم بکس شوی یا بېری.

… مګر په دې تمرکز نه کوي. کله چې تاسو، د ریاضیاتو د اوږدولو له لارې ستړي شوي یاست (شاید تاسو د پوهنتون له کورس څخه هم پیژندل شوي وي)، پریکړه وکړئ چې نمرې واخلئ او وګورئ چې څنګه واقعیا په عمل کې د دې سره کار کوئ، دا تاثر ستاسو په سر کې پاتې کیږي: دلته د جدي ریاضیاتو پراساس دی. په ښکاره ډول ښه خلک (دوه ریاضی پوهان - د ACM ګټونکي)، او نه یوازې څوک. هدف - د ویشلو لپاره - ترلاسه شو.

په هرصورت، د شمیر په اړه. یادول # دا یو مترادف دی natطبیعي شمېره:

ډول ډول څرګندونې شتون لري (typeexpr) او عددي څرګندونې (nat-expr). په هرصورت، دوی په ورته ډول تعریف شوي.

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

مګر په ګرامر کې دوی په ورته ډول تشریح شوي، i.e. دا توپیر باید یو ځل بیا په یاد وساتل شي او د لاس په واسطه پلي کولو کې واچول شي.

ښه، هو، د ټیمپلیټ ډولونه (vector<int>, vector<User>) یو عام پیژندونکی لري (#1cb5c415, i.e. که تاسو پوهیږئ چې زنګ ورته اعلان شوی

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

بیا تاسو نه یوازې د ویکتور انتظار کوئ ، بلکه د کاروونکو ویکتور ته. ډیر دقیق، باید انتظار وکړئ - په ریښتیني کوډ کې، هر عنصر، که یو ښکاره ډول نه وي، به یو جوړونکی ولري، او په ښه توګه په پلي کولو کې دا به اړین وي چې وګورئ - او موږ د دې ویکتور په هر عنصر کې دقیقا لیږل شوي یو هغه ډول؟ او که دا یو ډول PHP و، په کوم کې چې سرې کولی شي په مختلفو عناصرو کې مختلف ډولونه ولري؟

پدې مرحله کې، تاسو حیرانتیا پیل کوئ - ایا داسې TL ته اړتیا ده؟ شاید د کارټ لپاره دا ممکن وي چې د انسان سیریلائزر وکاروئ ، ورته پروټوبف چې دمخه شتون درلود؟ دا نظریه وه، راځئ چې عمل ته وګورو.

په کوډ کې د TL موجوده پلي کول

TL د VKontakte په کولمو کې زیږیدلی حتی د مشهورو پیښو څخه دمخه د Durov د ونډې پلور سره او (بيشکه)، حتی د ټیلیګرام پراختیا دمخه. او په خلاص سرچینه کې د لومړي پلي کولو سرچینې تاسو کولی شئ ډیری مسخره بیساچي ومومئ. او ژبه پخپله هلته په بشپړ ډول پلي شوې وه چې اوس په ټیلیګرام کې ده. د مثال په توګه، هشونه په سکیم کې هیڅ نه کارول کیږي (مطلب د جوړ شوي سیډوټایپ (لکه د ویکتور په څیر) د انحراف چلند سره). یا

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>;

دا د هش میپ ټیمپلیټ ډول تعریف دی ، د int - ډول جوړو ویکتور په توګه. په C++ کې به دا یو څه داسې ښکاري:

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

نو alpha - کلیدي کلمه! مګر یوازې په C++ کې تاسو کولی شئ T ولیکئ، مګر تاسو باید الفا، بیټا ولیکئ ... مګر د 8 پیرامیټرو څخه زیات نه، تصور په تیټا پای ته ورسید. نو داسې ښکاري چې یو وخت په سینټ پیټرزبورګ کې نږدې داسې خبرې اترې وې:

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

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

مګر دا د TL "عمومي" د لومړي ترتیب شوي پلي کولو په اړه و. راځئ چې په ریښتیني ټیلیګرام پیرودونکو کې د پلي کولو په اړه غور ته لاړ شو.

د باسیل کلمه:

واسیلي، [09.10.18 17:07] تر ټولو ډیر، خر له دې حقیقت څخه ګرم دی چې دوی د خلاصون یوه ډله جوړه کړه، او بیا یې په دوی باندې یو بولټ واچاوه، او د کوډجیجرټر یې په کرچونو پوښلی.
د پایلې په توګه، لومړی د ډاکس څخه pilot.jpg
بیا د jekichan.webp کوډ څخه

البته، د هغو خلکو څخه چې د الګوریتمونو او ریاضياتو سره اشنا دي، موږ تمه کولی شو چې دوی Aho، Ullman لوستلي وي، او د لسیزو په اوږدو کې د دوی د DSL تالیف کونکو لیکلو لپاره د حقیقت صنعت معیاري وسیلو سره آشنا دي، سمه ده؟ ..

لیکوال telegram-cli ویتالي والټمن دی، لکه څنګه چې د TLO بڼه د هغې (cli) حدودو څخه بهر د پیښې څخه پوهیدلی شي، د ټیم غړی - اوس د TL تحلیل لپاره کتابتون تخصیص شوی جلا جلاد هغې تاثر څه دی TL پارسر؟ ..

16.12 04:18 واسیلي: زما په نظر، یو چا په لیکس + یاک کې ماسټري نه ده کړې
16.12 04:18 واسیلي: که نه نو زه یې نه شم تشریح کولی
16.12 04:18 واسیلي: ښه، یا دوی ته په VK کې د لینونو شمیر لپاره پیسې ورکړل شوې
16.12 04:19 واسیلي: د نورو 3k+ کرښې<censored> د پارسر پر ځای

شاید یو استثنا؟ راځئ وګورو چې څنګه کوي دا رسمي پیرودونکی دی - د ټیلیګرام ډیسټاپ:

    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+ لینونه، یو څو منظم بیانونه + د ویکتور ډول ځانګړي قضیې، چې البته، په سکیم کې اعلان شوي لکه څنګه چې باید د TL نحو سره سم وي، مګر دوی دا په دې ترکیب کې واچوي، نور یې تجزیه کړئ. ... پوښتنه دا ده چې ولې له دې ټولو معجزو سره مخ شو؟иډیر پف، که هیڅوک دا د اسنادو سره سم تحلیل نه کوي؟!

په لاره کې ... په یاد ولرئ چې موږ د CRC32 چک په اړه خبرې وکړې؟ نو ، د ټیلیګرام ډیسټاپ کوډ جنریټر کې د دې ډولونو لپاره د استثنااتو لیست شتون لري په کوم کې چې محاسبه شوې CRC32 سمون نه خوري لکه څنګه چې په انځور کې ښودل شوي!

واسیلي، [18.12 22:49] او دلته تاسو باید فکر وکړئ چې ایا داسې TL ته اړتیا ده
که زه غواړم د بدیل پلي کولو سره ګډوډ کړم، زه به د لاین بریکونو داخلول پیل کړم، نیمایي پارسر به په څو لاین تعریفونو مات شي
tdesktop، په هرصورت، هم

د یو لینر په اړه ټکی په یاد ولرئ، موږ به لږ وروسته بیرته راګرځوو.

ښه، ټیلیګرام-کلی غیر رسمي دی، د ټیلیګرام ډیسټاپ رسمي دی، مګر د نورو په اړه څه؟ او څوک پوهیږي؟.. د Android پیرودونکي کوډ کې هیڅ سکیما پارسر شتون نلري (کوم چې د خلاصې سرچینې په اړه پوښتنې راپورته کوي ، مګر دا د دوهمې برخې لپاره دی) ، مګر د کوډ ډیری نورې مسخره ټوټې شتون درلود ، مګر د دوی په اړه لاندې فرعي برخه.

سریال کول په عمل کې کومې نورې پوښتنې راپورته کوي؟ د مثال په توګه، دوی خراب شوي، البته، د بټ ساحو او مشروط ساحو سره:

وصال: flags.0? true
پدې معنی چې ساحه موجوده ده او ریښتیا ده که بیرغ ترتیب شوی وي

وصال: flags.1? int
پدې معنی چې ساحه موجوده ده او اړتیا لري چې بې برخې شي

واسیلي: آس، مه سوځیږه، ته څه کوې!
واسیلي: په سند کې یو ځای یادونه شوې چې ریښتیا د صفر اوږدوالی یو بې ساری ډول دی، مګر دا غیر واقعیت دی چې د دوی له اسنادو څخه یو څه راټول کړي.
ویسیلي: په خلاص پلي کولو کې هم داسې څه شتون نلري ، مګر ډیری کرچونه او پروپس شتون لري

د ټیلیون په اړه څنګه؟ د MTProto موضوع ته په پام سره، یو مثال - په اسنادو کې داسې ټوټې شتون لري، مګر نښه % دا یوازې د "د ورکړل شوي بېئر ډول سره مطابقت" په توګه تشریح شوی، د بیلګې په توګه. په لاندې مثالونو کې، یا یوه تېروتنه، یا یو څه غیر مستند شوي:

واسیلي, [22.06.18/18/38 XNUMX:XNUMX] په یو ځای کې:

msg_container#73f1f8dc messages:vector message = MessageContainer;

په بل ډول:

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

او دا دوه لوی توپیرونه دي، په ریښتینې ژوند کې یو ډول ناپاک ویکتور راځي

ما د ویکتور تعریفونه نه دي لیدلي او نه یې لیدلي

تحلیل په ټیلیون کې د لاس په واسطه لیکل شوی

د هغه سکیما تعریف بیان کړ msg_container

بیا بیا، پوښتنه د٪ په اړه پاتې ده. دا نه دی تشریح شوی.

Vadim Goncharov, [22.06.18/19/22 XNUMX:XNUMX PM] او په tdesktop کې؟

واسیلي، [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 (د 1KB په واسطه د ویش وړ)
  • 524288 % part_size = 0 (512KB باید په مساوي ډول د برخې_size په واسطه تقسیم شي)

وروستۍ برخه د دې شرایطو پوره کولو ته اړتیا نلري، په دې شرط چې اندازه یې د برخې_size څخه کمه وي.

هره برخه باید د ترتیب شمیره ولري، فایل_برخهد 0 څخه تر 2,999 پورې ارزښت سره.

د فایل ویشلو وروسته تاسو اړتیا لرئ چې په سرور کې د خوندي کولو لپاره یوه طریقه غوره کړئ. کارول upload.saveBigFilePart په هغه صورت کې چې د فایل بشپړ اندازه له 10 MB څخه زیاته وي او upload.saveFilePart د کوچنیو فایلونو لپاره.
[...] د لاندې معلوماتو د ننوتلو غلطیو څخه یوه ممکن بیرته راستانه شي:

  • FILE_PARTS_INVALID - د برخو ناسم شمیر. ارزښت په منځ کې نه دی 1..3000

ایا له دې څخه کوم یو په سکیما کې شتون لري؟ ایا دا په یو ډول د TL له لارې د بیان وړ دی؟ نه. مګر بخښنه غواړم، حتی د زاړه فیشن ټربو پاسکل د دې توان درلود چې د لخوا ورکړل شوي ډولونه تشریح کړي. سلسلې. او هغه کولی شي یو بل کار وکړي، چې اوس یې په نوم پیژندل کیږي enum - یو ډول چې د یو ثابت (کوچني) ارزښتونو شمیرې لري. په ژبو کې لکه C - شمیره، تاسو په پام کې ونیسئ، موږ تر دې دمه یوازې د ډولونو په اړه خبرې کړې دي. شمېرې. مګر دلته سرې، تارونه هم شتون لري ... د مثال په توګه، دا به ښه وي چې تشریح کړئ چې دا تار یوازې د تلیفون شمیره لري، سمه ده؟

له دې څخه هیڅ یو په TL کې ندي. مګر شتون لري، د بیلګې په توګه، په JSON سکیما کې. او که بل څوک د 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. یا برعکس. مګر دا کار وکړ! دا دی، سرور ډول ته پام نه کوي. دا څنګه کیدای شي؟ ځواب، شاید، د ټیلګرام-کلی څخه د کوډ ټوټې لخوا هڅول کیږي:

  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 نسخو وروسته، موږ په پای کې هغه څه ته ورسیږو چې د انټرنیټ پروتوکولونو کې بیرته په 80s کې ترسره شوي - نسخه خبرې اترې یو ځل د پیوستون په پیل کې!

نو بیا څه شی دی؟ ...

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

او اوس تاسو خندا کولی شئ. یوازې د نورو 9 پرتونو وروسته ، یو نړیوال جوړونکی د نسخې شمیرې سره په پای کې اضافه شو ، کوم چې د پیوستون په پیل کې یوازې یو ځل ویل کیدو ته اړتیا لري ، او په پرتونو کې معنی ورک شوی ښکاري ، اوس دا یوازې یو مشروط نسخه ده ، لکه بل هر ځای. ستونزه حل شوه.

سمه ده؟...

واسیلي, [16.07.18/14/01 XNUMX:XNUMX PM] د جمعې په ورځ ما فکر کاوه:
ټیلیسرور پرته له غوښتنې څخه پیښې لیږي. غوښتنې باید په InvokeWithLayer کې وتړل شي. سرور تازه معلومات نه لټوي، د ځوابونو او تازه معلوماتو لپاس کولو لپاره هیڅ جوړښت شتون نلري.

هغوی. پیرودونکی نشي کولی هغه پرت مشخص کړي په کوم کې چې هغه تازه غواړي

Vadim Goncharov, [16.07.18/14/02 XNUMX:XNUMX PM] ایا InvokeWithLayer په اصولو کې یو بسنه نه ده؟

Vasily, [16.07.18/14/02 XNUMX:XNUMX PM] دا یوازینۍ لار ده

Vadim Goncharov, [16.07.18/14/02 XNUMX:XNUMX PM] کوم چې باید د غونډې په پیل کې د پرت کولو معنی ولري

د لارې په توګه، دا د دې څخه تعقیب کیږي چې د پیرودونکي ښکته کول ندي چمتو شوي

تازه معلومات، i.e. ډول Updates په سکیم کې، دا هغه څه دي چې سرور پیرودونکي ته د API غوښتنې په ځواب کې نه لیږي، مګر پخپله کله چې پیښه رامنځته کیږي. دا یوه پیچلې موضوع ده چې په بل پوسټ کې به پرې بحث وشي، مګر د اوس لپاره دا مهمه ده چې پوه شئ چې سرور تازه معلومات راټولوي حتی کله چې پیرودونکي آفلاین وي.

په دې توګه، کله چې د لپاس کولو څخه ډډه کول هر یو بسته د دې نسخه په ګوته کولو لپاره ، له همدې امله لاندې احتمالي ستونزې په منطقي ډول رامینځته کیږي:

  • سرور مراجعینو ته تازه معلومات لیږي مخکې لدې چې پیرودونکي وویل چې کوم نسخه یې ملاتړ کوي
  • د مراجعینو د لوړولو وروسته باید څه وشي؟
  • څوک تضمیندا چې د پرت شمیرې په اړه د سرور نظر به په پروسه کې بدلون ونلري؟

ایا تاسو فکر کوئ چې دا خالص نظري فکر دی، او په عمل کې دا نشي کیدی، ځکه چې سرور په سمه توګه لیکل شوی (په هر حالت کې، دا ښه ازموینه کیږي)؟ ها! که څنګه!

دا په حقیقت کې هغه څه دي چې موږ یې د اګست په میاشت کې تیر کړل. د اګست په 14، پیغامونه خپاره شول چې د ټیلیګرام سرورونو کې یو څه تازه کیږي ... او بیا په لاګونو کې:

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 کې نه پیژندل شوی - دا د لاسلیکونو لخوا بائنری دی، نور په جریان کې ټول ځي، کوډ کول به ناممکن شي. په داسې حالت کې څه وکړي؟

ښه، لومړی شی چې د هر چا ذهن ته راځي هغه له مینځه وړل او بیا هڅه کول دي. مرسته ونه کړه. موږ د CRC32 ګوګل ګوګل کړی - دا د سکیم 73 څخه شیان وګرځیدل، که څه هم موږ په 82 سکیم کار کړی. موږ لاګ ته په احتیاط سره ګورو - د دوه مختلف سکیمونو څخه پیژندونکي شتون لري!

شاید ستونزه زموږ په غیر رسمي پیرودونکي کې خالصه وي؟ نه، موږ د ټیلیګرام ډیسټاپ 1.2.17 چلوو (هغه نسخه چې د یو شمیر لینکس توزیعونو سره چمتو کیږي)، دا د استثناء لاګ ته لیکي: د MTP غیر متوقع ډول id #b5223b0f په MTPMessageMedia کې لوستل کیږي ...

د ټیلیګرام پروتوکول او تنظیمي چلندونو انتقاد. برخه 1، تخنیکي: له سکریچ څخه د پیرودونکي لیکلو تجربه - TL, MT

ګوګل وښودله چې ورته ستونزه لا دمخه د یو غیر رسمي پیرودونکي سره پیښ شوې وه ، مګر بیا د نسخې شمیرې او په وینا یې ، انګیرنې توپیر درلود ...

نو څه وکړي؟ واسیلي او زه جلا شو: هغه هڅه وکړه چې سکیم 91 ته تازه کړي، ما پریکړه وکړه چې یو څو ورځې انتظار وکړم او 73 ته هڅه وکړم. دواړه میتودونه کار کوي، مګر دا چې دوی تجربه لرونکي دي، پدې نه پوهیږي چې تاسو څومره نسخې ته اړتیا لرئ چې پورته یې کړئ. یا ښکته، او نه هم تاسو باید څومره وخت انتظار وکړئ.

وروسته ، ما د وضعیت بیا تولید کولو اداره وکړه: موږ پیرودونکي پیل کوو ، بند یې کړو ، سکیم بل پرت ته بیا تنظیم کړو ، بیا پیل کړئ ، ستونزه بیا ونیسئ ، پخواني ته بیرته راشئ - اوف ، سکیم بدل نه کړئ او پیرودونکي د څو لپاره بیا پیل کړئ. دقیقې به مرسته وکړي. تاسو به د مختلف پرتونو څخه د ډیټا جوړښتونو ترکیب ترلاسه کړئ.

وضاحت؟ لکه څنګه چې تاسو د مختلف غیر مستقیم نښانو څخه اټکل کولی شئ، سرور په مختلفو ماشینونو کې ډیری مختلف ډوله پروسې لري. ډیری احتمال، یو له هغه سرورونو څخه چې د "بفرینګ" لپاره مسؤل دی په کتار کې هغه څه واچوي چې لوړ خلکو ورته ورکړي، او دوی یې په هغه سکیم کې ورکړي چې د نسل په وخت کې وو. او تر هغه چې دا کتار "خراب" نه وي، د دې په اړه هیڅ شی نشي کیدی.

پرته لدې چې ... مګر دا یو وحشتناکه کرچ دی؟!.. نه، مخکې له دې چې د لیوني نظرونو په اړه فکر وکړئ، راځئ چې د رسمي مراجعینو کوډ وګورو. د Android نسخه کې ، موږ هیڅ TL پارسر نه موندلو ، مګر موږ د (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

هلکانو، ایا تاسو حتی په یوه طبقه کې پریکړه نشئ کولی؟! ښه، ښه، "دوه"، راځئ چې ووایو، په تېروتنه خوشې شوي، ښه، دا پیښیږي، مګر درې؟ .. سمدستي بیا په ورته ریک کې؟ دا څه ډول فحشا ده، بښنه غواړم؟

په هرصورت ، د ټیلیګرام ډیسټاپ سرچینو کې ورته شی پیښیږي - که داسې وي ، او سکیم ته په پرله پسې ډول څو ژمنې د دې پرت شمیره نه بدلوي ، مګر یو څه سم کړئ. په داسې شرایطو کې چې د سکیم لپاره د معلوماتو رسمي سرچینه شتون نلري، زه د رسمي مراجعینو سرچینو پرته له کوم ځای څخه ترلاسه کولی شم؟ او تاسو یې له هغه ځای څخه اخلئ، تاسو نشئ کولی ډاډ ترلاسه کړئ چې سکیم په بشپړ ډول سم دی تر هغه چې تاسو ټولې میتودونه و ازموئ.

دا څنګه حتی ازموینه کیدی شي؟ زه امید لرم چې د واحد ، فعال او نورو ازموینو مینه وال به په نظرونو کې شریک کړي.

ښه، راځئ چې د کوډ بله برخه وګورو:

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;

دا "په لاسي ډول رامینځته شوی" تبصره دلته وړاندیز کوي چې د دې فایل یوازې برخه د لاس په واسطه لیکل شوې (ایا تاسو د ساتنې خوب تصور کولی شئ؟) ، او پاتې نور د ماشین لخوا رامینځته شوي. په هرصورت، بیا بله پوښتنه راپورته کیږي - دا چې سرچینې شتون لري په بشپړه توګه نه (په لینکس کرنل کې د GPL لاندې یو لا بلب) ، مګر دا دمخه د دوهمې برخې لپاره موضوع ده.

خو بس. راځئ چې په سر کې پروتوکول ته لاړ شو چې دا ټول سریالیزیشن تعقیبوي.

MT پروټو

نو راځئ چې خلاص کړو عمومي توضیحات и د پروتوکول تفصيلي توضیحات او لومړی شی چې موږ یې ټکان ورکوو هغه اصطلاحات دي. او د هر څه په کثرت سره. په عموم کې، دا د ټیلیګرام سوداګریز نښه ښکاري - په مختلفو ځایونو کې شیان په مختلفو لارو، یا په یوه کلمه کې مختلف شیان، یا برعکس (د مثال په توګه، په لوړه کچه API کې که تاسو د سټیکر پیک وګورئ - دا هغه څه نه دي چې تاسو فکر کاوه).

د مثال په توګه، "پیغام" (پیغام) او "غونډه" (غونډه) - دلته دوی د ټیلیګرام پیرودونکي د معمول انٹرفیس په پرتله یو څه توپیر لري. ښه، هر څه د پیغام سره روښانه دي، دا د OOP په شرایطو کې تشریح کیدی شي، یا په ساده ډول د "پیکج" کلمه ویل کیږي - دا د ټرانسپورټ کچه ټیټه ده، د انټرفیس په څیر ورته پیغامونه شتون نلري، ډیر څه شتون لري. د خدمت کوونکو څخه. مګر غونډه ... مګر لومړی شیان لومړی.

د ترانسپورت طبقه

لومړی شی ترانسپورت دی. موږ ته به د 5 اختیارونو په اړه وویل شي:

  • TCP
  • ویب پاocketه
  • د HTTPS په اړه ویب ساکټ
  • HTTP
  • HTTPS

Vasily, [15.06.18/15/04 XNUMX:XNUMX PM] او د UDP ټرانسپورټ هم شتون لري، مګر دا مستند نه دی

او TCP په دریو ډولونو کې

لومړی د TCP په اړه UDP ته ورته دی، هر پاکټ کې د ترتیب شمیره او یو crc شامل دي
ولې په موټر کې د ډاک لوستل دومره دردناک دي؟

ښه اوس هلته TCP لا دمخه په 4 ډولونو کې:

  • لنډول
  • منځګړیتوب
  • پیډ شوی منځنی
  • بشپړ

ښه، د MTProxy لپاره پیډ شوی منځګړیتوب، دا وروسته د پیژندل شویو پیښو له امله اضافه شو. مګر ولې دوه نورې نسخې (په ټوله کې درې)، کله چې یو کولی شي؟ ټول څلور په اصل کې یوازې د اصلي MTProto اوږدوالی او تادیه کولو څرنګوالي کې توپیر لري ، کوم چې به نور بحث وشي:

  • په لنډیز کې دا 1 یا 4 بایټ دی مګر نه 0xef بیا بدن
  • په منځګړیتوب کې دا د 4 بایټ اوږدوالی او ساحه ده، او لومړی ځل چې پیرودونکي باید واستوي 0xeeeeeeee د دې لپاره چې وښيي دا منځګړیتوب دی
  • په بشپړ ډول، ترټولو روږدي، د شبکې له نظره: اوږدوالی، د ترتیب شمیره، او هغه نه چې اساسا د MTProto، بدن، CRC32 دی. هو، دا ټول په TCP کې. کوم چې موږ ته د بایټ سیریل جریان په توګه د باور وړ ټرانسپورټ چمتو کوي ، هیڅ ترتیب ته اړتیا نشته ، په ځانګړي توګه چیکسم. ښه، اوس به زه اعتراض وکړم چې TCP 16-bit چیکسم لري، نو د معلوماتو فساد واقع کیږي. عالي ، پرته لدې چې موږ واقعیا د 16 بایټس څخه ډیر اوږد هیشونو سره کریپټوګرافیک پروتوکول لرو ، دا ټولې غلطۍ - او حتی نور - به په لوړه کچه د SHA غلط میچ کې ونیول شي. پدې اړه په CRC32 کې هیڅ ټکی نشته.

راځئ چې لنډیز پرتله کړو، چیرې چې یو بایټ اوږدوالی ممکن وي، د منځګړیتوب سره، کوم چې "په هغه صورت کې چې د 4-بایټ ډیټا ترتیب ته اړتیا وي" توجیه کوي، کوم چې خورا بې معنی دی. څه، داسې انګیرل کیږي چې د ټیلیګرام پروګرام کونکي دومره بې کاره دي چې دوی نشي کولی د ساکټ څخه ډاټا په ترتیب شوي بفر کې ولولي؟ تاسو لاهم باید دا کار وکړئ ، ځکه چې لوستل کولی شي تاسو ته هر ډول بایټ بیرته راوباسي (او دلته پراکسي سرورونه هم شتون لري ، د مثال په توګه ...). یا ، له بلې خوا ، ولې د لنډیز سره زحمت وکړئ که چیرې موږ لاهم د 16 بایټونو څخه په سر کې لوی پیډینګونه لرو - 3 بایټ خوندي کړئ ورپسې ?

یو داسې تاثر ترلاسه کوي چې نیکولای دوروف د ریښتیني عملي اړتیا پرته د شبکې پروتوکولونو په شمول د بایسکلونو اختراع کولو سره خورا مینه لري.

د ترانسپورت نور انتخابونه، په شمول. ویب او MTProxy، موږ به اوس په پام کې ونیسو، شاید په بل پوسټ کې، که چیرې غوښتنه وي. موږ به اوس یوازې د دې MTProxy په اړه یادونه وکړو چې په 2018 کې د خوشې کیدو وروسته سمدلاسه ، چمتو کونکو په چټکۍ سره د دې بلاک کول زده کړل ، چې هدف یې بای پاس بند کړئد د بسته اندازه! او همدارنګه دا حقیقت چې په C کې د MTProxy سرور لیکل شوی (بیا د والټمن لخوا) په غیر ضروري ډول د لینکس ځانګړتیاو سره تړلی و، که څه هم دا په هیڅ ډول اړین نه و (فیل کولین به تایید کړي)، او دا چې ورته سرور یا په Go یا Node.js کې له سلو څخه لږ لاینونه مناسب.

خو موږ به د نورو مسايلو په پام کې نيولو سره د دې برخې په پای کې د دغو کسانو د تخنيکي سواد په اړه پايلې ته ورسوو. د اوس لپاره، راځئ چې د OSI پنځم پرت ته لاړ شو، ناستې - په کوم کې چې دوی د MTProto ناسته کېښوده.

کیلي، پیغامونه، ناستې، Diffie-Hellman

دوی دا هلته په بشپړ ډول په سمه توګه ندي ایښودل ... A سیشن ورته ناسته نه ده چې د فعال غونډو لاندې انٹرفیس کې لیدل کیږي. مګر په ترتیب سره.

د ټیلیګرام پروتوکول او تنظیمي چلندونو انتقاد. برخه 1، تخنیکي: له سکریچ څخه د پیرودونکي لیکلو تجربه - TL, MT

دلته موږ د ټرانسپورټ پرت څخه د پیژندل شوي اوږدوالي بایټ تار ترلاسه کړ. دا یا یو کوډ شوی پیغام یا ساده متن دی - که موږ لاهم د کلیدي خبرو اترو په مرحله کې یو او واقعیا یې کوو. موږ د "کیلي" په نوم د مفاهیمو کومې ډلې په اړه خبرې کوو؟ راځئ چې دا مسله پخپله د ټیلیګرام ټیم لپاره روښانه کړو (زه د سهار په 4 بجو د ستړي مغز څخه د انګلیسي څخه د خپل سند د ژباړلو لپاره بخښنه غواړم، دا اسانه وه چې ځینې جملې پریږدم لکه څنګه چې دوی دي):

په نوم دوه ادارې شتون لري غونډه - یو د "اوسني غونډو" لاندې د رسمي پیرودونکو UI کې ، چیرې چې هره ناسته د ټول وسیلې / 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 په نوي ډي سي کې.
  • ټول ورته، ممکن څو خلاص وي د MTProto ناستې (هر یو د خپل ځان سره session_id) دې نوي ډي سي ته، لاندې د هغه د 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 په د ټیلیګرام څخه د ډیفي هیلمن نسخه. راځئ چې د اسنادو د پوهیدو هڅه وکړو ...

Vasily, [19.06.18/20/05 1:255] data_with_hash := SHAXNUMX(ډاټا) + ډاټا + (هر ډول تصادفي بایټ)؛ داسې چې اوږدوالی یې د XNUMX بایټ سره مساوي وي؛
encrypted_data := RSA(data_with_hash, server_public_key); د 255-بایټ اوږده شمیره (لوی انډیان) د اړتیا وړ ماډلونو باندې اړین ځواک ته پورته کیږي، او پایله د 256-بایټ شمیرې په توګه ساتل کیږي.

دوی یو څه ډوپ DH ترلاسه کړ

د سالم شخص DH په څیر نه ښکاري
په dx کې هیڅ دوه عامه کیلي نشته

ښه، په پای کې، موږ دا معلومه کړه، مګر ټوټه پاتې شوه - د کار ثبوت د پیرودونکي لخوا ترسره کیږي چې هغه د دې توان درلود چې شمیره فکتور کړي. د DoS بریدونو په وړاندې د خوندیتوب ډول. او د RSA کیلي یوازې یو ځل په یو لوري کې کارول کیږي، په اصل کې د کوډ کولو لپاره new_nonce. مګر پداسې حال کې چې دا ښکاري ساده عملیات بریالي کیږي، تاسو به له څه سره مخ شئ؟

واسیلي, [20.06.18/00/26 XNUMX:XNUMX] زه لا تر اوسه د غوښتنلیک غوښتنې ته نه یم رسیدلی

ما DH ته غوښتنه واستوله

او، د ټرانسپورټ په ډاک کې دا لیکل شوي چې دا کولی شي د غلطۍ کوډ 4 بایټ سره ځواب ووايي. او دا دی

ښه، هغه ماته وویل - 404، نو څه؟

دلته زه هغه ته یم: "د سرور کیلي سره کوډ شوی خپل ایفیګن د داسې او داسې نورو ګوتو نښې سره ونیسئ ، زه DH غواړم" ، او دا په احمقانه ډول 404 ځواب ورکوي.

تاسو به د داسې سرور ځواب په اړه څه فکر کوئ؟ چې څه کول پکار دي؟ هیڅوک نشته چې پوښتنه یې وکړي (مګر په دویمه برخه کې نور هم).

دلته په ډاکه کې د ټولو ګټو کار دی

زه نور څه نه لرم، ما یوازې د شمیرو د بدلولو خوب لیدلی

دوه 32 بټ شمیرې. ما دوی د هرچا په څیر بسته کړل

مګر نه، دا دوه دي چې تاسو اړتیا لرئ لومړی په یوه لیکه کې د BE په توګه

Vadim Goncharov, [20.06.18/15/49 404:XNUMX PM] او د دې له امله XNUMX؟

واسیلي، [20.06.18/15/49 XNUMX:XNUMX PM] هو!

Vadim Goncharov, [20.06.18/15/50 XNUMX:XNUMX PM] نو زه نه پوهیږم چې هغه څه شی "موندلی نه دی"

واسیلي، [20.06.18 15:50] تقريبا

ما په ساده تقسیم کونکو کې دومره تخریب ونه موندل))

حتی د تېروتنې راپور ورکولو کې مهارت نه درلود

Vasily, [20.06.18/20/18 5:XNUMX PM] اوه، MDXNUMX هم شته. دمخه درې مختلف هشونه

د ګوتو کلیدي نښه په لاندې ډول محاسبه کیږي:

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

SHA1 او sha2

نو راځئ چې واچوو auth_key 2048 بټونه په اندازې کې موږ د ډیفي هیلمن مطابق ترلاسه کړل. ورپسی څه دي؟ بیا موږ پوهیږو چې د دې کیلي ټیټ 1024 بټونه په هیڅ ډول نه کارول کیږي ... مګر راځئ چې د اوس لپاره پدې اړه فکر وکړو. پدې مرحله کې، موږ د سرور سره یو شریک راز لرو. د TLS ناستې یو انالوګ رامینځته شوی ، یو خورا ګران پروسیجر. مګر سرور په دې اړه هیڅ نه پوهیږي چې موږ څوک یو! تر اوسه نه، په حقیقت کې جواز. هغوی. که تاسو د "لاګ ان پاسورډ" په اړه فکر کوئ، لکه څنګه چې دا په ICQ کې کارول کیده، یا لږترلږه "لاګ ان کیلي"، لکه څنګه چې په SSH کې (د مثال په توګه، په ځینو ګیتلاب / ګیتوب کې). موږ بې نومه شو. او که سرور موږ ته ځواب ووایی "دا د تلیفون شمیرې د بل DC لخوا خدمت کیږي"؟ یا حتی "ستاسو د تلیفون شمیره منع ده"؟ ترټولو غوره شی چې موږ یې کولی شو کیلي په دې امید کې خوندي کول دي چې دا به لاهم ګټور وي او تر هغه وخته خراب نه وي.

په هرصورت، موږ دا د ریزرویشنونو سره "ترلاسه" کړل. د مثال په توګه، ایا موږ په سرور باور لرو؟ ایا هغه جعلي دی؟ موږ کریپټوګرافیک چک ته اړتیا لرو:

واسیلي، [21.06.18/17/53 2:XNUMX PM] دوی ګرځنده پیرودونکو ته وړاندیز کوي چې د XNUMXkbit شمیره د سادګۍ لپاره وګوري)

مګر دا په بشپړه توګه روښانه نه ده، nafeijoa

واسیلي, [21.06.18/18/02 XNUMX:XNUMX] ډاک نه وايي چې څه وکړي که دا ساده نه وي

نه ویل کیږي. راځئ وګورو چې د Android لپاره رسمي پیرودونکي پدې قضیه کې څه کوي؟ الف دا هغه څه دي (او هو، ټوله فایل هلته په زړه پورې دی) - لکه څنګه چې دوی وايي، زه به یې دلته پریږدم:

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

نه، البته هلته ځینې د یو شمیر سادګۍ لپاره چکونه شتون لري، مګر په شخصي توګه زه نور په ریاضي کې کافي پوهه نلرم.

ښه، موږ ماسټر کلی ترلاسه کړ. د ننوتلو لپاره، i.e. غوښتنې لیږل، دا اړینه ده چې نور کوډ کول ترسره کړئ، مخکې له دې چې د AES په کارولو سره.

د پیغام کیلي د پیغام د بدن د SHA128 د 256 منځني بټونو په توګه تعریف شوی (د سیشن، پیغام ID، او داسې نور) په شمول، د پیډینګ بایټ په شمول، د 32 بایټس لخوا وړاندې شوي چې د اختیار کولو کیلي څخه اخیستل شوي.

واسیلي, [22.06.18/14/08 XNUMX:XNUMX PM] اوسط کوچیان

ترلاسه کړ auth_key. ټول. دوی نور ... دا د ډاکونو څخه روښانه نه ده. د خلاصې سرچینې کوډ مطالعه کولو لپاره وړیا احساس وکړئ.

په یاد ولرئ چې MTProto 2.0 د 12 څخه تر 1024 بایټس پیډینګ ته اړتیا لري، بیا هم د دې شرط تابع دي چې د پایلې پیغام اوږدوالی په 16 بایټس ویشل کیږي.

نو څومره پیډینګ باید دننه شي؟

او هو، دلته هم د تېروتنې په صورت کې 404

که یو څوک په دقت سره ډیاګرام او د اسنادو متن مطالعه کړي، هغه ولیدل چې هلته MAC نشته. او دا چې AES په ځینې IGE حالت کې کارول کیږي چې بل چیرې نه کارول کیږي. دوی، البته، د دې په اړه په خپلو پوښتنو کې لیکي ... دلته، لکه، د پیغام کلید پخپله په ورته وخت کې د ډیکریټ شوي ډیټا SHA هش دی چې د بشپړتیا چک کولو لپاره کارول کیږي - او د بې اتفاقۍ په صورت کې، اسناد ځینې ​​​​دلیل وړاندیز کوي چې دوی په خاموشۍ سره له پامه غورځوي (مګر د امنیت په اړه څه ، ناڅاپه موږ مات کړئ؟).

زه کریپټوګرافر نه یم ، شاید پدې حالت کې پدې حالت کې د نظري نظر څخه هیڅ غلط نه وي. مګر زه کولی شم حتما د یوې عملي ستونزې نوم ورکړم ، د ټیلیګرام ډیسټاپ مثال په کارولو سره. دا محلي زیرمه کوډ کوي (دا ټول D877F783D5D3EF8C) په ورته ډول په MTProto کې پیغامونه (یوازې پدې حالت کې، نسخه 1.0)، د بیلګې په توګه. لومړی د پیغام کیلي، بیا پخپله ډاټا (او بل چیرې اصلي لوی auth_key 256 بایټس، پرته له دې msg_key بې ګټې). نو، ستونزه په لویو فایلونو کې د پام وړ کیږي. د مثال په توګه ، تاسو اړتیا لرئ د معلوماتو دوه کاپي وساتئ - کوډ شوي او کوډ شوي. او که چیرې میګابایټ شتون ولري ، یا د ویډیو سټینګ کول ، د مثال په توګه؟ .. د سیفر متن وروسته د MAC سره کلاسیک سکیمونه تاسو ته اجازه درکوي چې لوستل یې کړئ ، سمدلاسه یې لیږدول. او د MTProto سره تاسو باید په لومړی کې ټول پیغام کوډ یا کوډ کړئ، یوازې بیا یې شبکې یا ډیسک ته انتقال کړئ. له همدې امله، د ټیلیګرام ډیسټاپ په وروستي نسخو کې په کیچ کې user_data بله بڼه لا دمخه کارول شوې ده - د AES سره په CTR حالت کې.

Vasily, [21.06.18/01/27 20:XNUMX AM] اوه، ما وموندله چې IGE څه شی دی: IGE په اصل کې د کربروس لپاره د "مستند کوډ کولو حالت" کې لومړۍ هڅه وه. دا یوه ناکامه هڅه وه (دا د بشپړتیا ساتنه نه کوي)، او باید لیرې شي. دا د تصدیق کونکي کوډ کولو حالت لپاره د XNUMX کلن لټون پیل و چې کار کوي ، کوم چې پدې وروستیو کې د OCB او GCM په څیر حالتونو کې پای ته رسیدلی.

او اوس د کارټ اړخ څخه دلیلونه:

د ټیلیګرام تر شا ټیم، د نیکولای دوروف په مشرۍ، د ACM شپږ اتلان لري، چې نیمایي یې په ریاضي کې Ph.Ds لري. دوی د MTProto اوسنی نسخه په لاره اچولو کې شاوخوا دوه کاله وخت واخیست.

څه مسخره ده. دوه کاله ټیټې کچې ته

یا موږ کولی شو یوازې tls واخلو

ښه، راځئ ووایو چې موږ کوډ کول او نور لنډیزونه ترسره کړي دي. ایا موږ کولی شو په پای کې د TL- سیریل شوي غوښتنې واستوو او ځوابونه بې اساسه کړو؟ نو څه باید ولیږل شي او څنګه؟ دلته طریقه ده initConnectionشاید دا دی؟

Vasily, [25.06.18/18/46 XNUMX:XNUMX PM] پیوستون پیلوي او د کارونکي وسیله او غوښتنلیک کې معلومات خوندي کوي.

دا app_id، device_model، system_version، app_version او lang_code مني.

او ځینې پوښتنې

د تل په څیر اسناد. د خلاصې سرچینې مطالعې لپاره وړیا احساس وکړئ

که هرڅه د invokeWithLayer سره تقریبا روښانه وو، نو دا څه دي؟ دا معلومه شوه چې فرض کړئ موږ لرو - پیرودونکي دمخه د سرور څخه د پوښتنې کولو لپاره یو څه درلود - دلته یوه غوښتنه شتون لري چې موږ یې لیږو:

Vasily, [25.06.18/19/13 XNUMX:XNUMX] د کوډ په واسطه قضاوت کول، لومړی زنګ په دې کثافاتو کې پوښل شوی، او کثافات پخپله په بلنه کې دی

ولې 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 شمیرې سره خطا ترلاسه کړو. د دې لپاره چې معلومه کړو چې کوم IP پته موږ اړتیا لرو د DC شمیرې سره وصل شو، موږ به ورسره مرسته وکړو help.getConfig. یو وخت یوازې 5 داخلې وې، مګر د 2018 د پیژندل شویو پیښو وروسته، شمیره د پام وړ لوړه شوې.

اوس راځئ چې په یاد ولرئ چې موږ پدې مرحله کې په نامعلوم سرور کې ترلاسه کړل. ایا دا ډیره ګرانه نه ده چې یوازې د IP پته ترلاسه کړئ؟ ولې دا او نور عملیات د MTProto په نه کوډ شوي برخه کې ترسره کوئ؟ زه یو اعتراض اورم: "تاسو څنګه ډاډ ترلاسه کولی شئ چې دا RKN نه دی چې د جعلي پتې سره ځواب ووایی؟" دې ته موږ په حقیقت کې په رسمي مراجعینو کې یادونه کوو سرایت شوي RSA کیلي, i.e. تاسو کولی شئ یوازې ګډون دا معلومات. په حقیقت کې ، دا دمخه د بای پاس کولو لاکونو معلوماتو لپاره ترسره شوی چې پیرودونکي د نورو چینلونو له لارې ترلاسه کوي (دا منطقي ده چې دا پخپله په 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 موضوع کې یو څه له لاسه ورکړی؟ د حیرانتیا خبره نشته:

Vasily, [28.06.18/02/04 2:XNUMX AM] Mm، دوی په eXNUMXe کې د ځینو الګوریتمونو له لارې غږیږي

Mtproto د دواړو ډومینونو لپاره د کوډ کولو الګوریتمونه او کیلي تعریفوي، په بیله بیا یو څه د ریپر جوړښت

مګر دوی په دوامداره توګه د مختلف سټیک کچې مخلوط کوي ، نو دا تل روښانه نده چې mtproto چیرته پای ته رسیدلی او راتلونکی کچه پیل شوې.

دوی څنګه مخلوط دي؟ ښه، دلته د PFS لپاره ورته لنډمهاله کیلي ده، د بیلګې په توګه (په لاره کې، د ټیلیګرام ډیسټاپ نه پوهیږي چې دا څنګه وکړي). دا د API غوښتنې لخوا اجرا کیږي auth.bindTempAuthKey, i.e. له لوړې کچې څخه. مګر په ورته وخت کې، دا په ټیټه کچه د کوډ کولو سره مداخله کوي - د هغې وروسته، د بیلګې په توګه، تاسو اړتیا لرئ چې دا بیا ترسره کړئ initConnection وغيره، دا نه ده یوازې عادي غوښتنه. په جلا توګه، دا هم وړاندې کوي چې تاسو کولی شئ په DC کې یوازې یو لنډمهاله کیلي ولرئ، که څه هم ساحه auth_key_id په هر پیغام کې تاسو ته اجازه درکوي لږترلږه هر پیغام کیلي بدل کړئ، او دا چې سرور حق لري په هر وخت کې لنډمهاله کیلي "هیر" کړي - پدې حالت کې څه وکړي، اسناد نه وايي ... ښه، ولې دا به ممکنه نه وي چې څو کیلي ولرئ، لکه څنګه چې د راتلونکي مالګې سیټ سره، مګر؟

د MTProto موضوع کې د پام وړ یو څو نور شیان شتون لري.

د پیغام پیغامونه، msg_id، msg_seqno، اعترافونه، په غلط لوري کې پینګونه او نور محاورې

تاسو ولې اړتیا لرئ د دوی په اړه پوه شئ؟ ځکه چې دوی یو سطح لوړ "لیک" کوي، او تاسو اړتیا لرئ د دوی په اړه پوه شئ کله چې د API سره کار کوي. فرض کړئ چې موږ د msg_key سره علاقه نلرو، ټیټه کچه زموږ لپاره هرڅه کوډ کړي. مګر د کوډ شوي ډیټا دننه ، موږ لاندې ساحې لرو (د ډیټا اوږدوالی هم پوهیږو چې پیډینګ چیرې دی ، مګر دا مهم ندي):

  • مالګه - int64
  • session_id - int64
  • پیغام_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-bit شمیره د "منځپانګو پورې اړوند" پیغامونو دوه چنده سره مساوي ده (هغه چې اعتراف ته اړتیا لري، او په ځانګړي توګه هغه چې کانټینرونه ندي) د دې پیغام څخه دمخه د لیږونکي لخوا رامینځته شوي او وروسته د یو لخوا زیات شوي که چیرې اوسنی پیغام یو وي. د منځپانګې اړوند پیغام. یو کانټینر تل د هغې د ټولو مینځپانګو وروسته تولید کیږي؛ له همدې امله، د دې ترتیب شمیره د پیغامونو د ترتیب شمیرو څخه لوی یا مساوي دی چې پدې کې شامل دي.

دا کوم ډول سرکس دی چې د 1 زیاتوالي سره، او بیا بل 2؟ .. زه شکمن یم چې اصلي معنی "د ACK لپاره ټیټه ده، پاتې نور یو شمیر دی"، مګر پایله سمه نه ده - په ځانګړې توګه، دا معلومه شوه چې دا لیږل کیدی شي څو تصدیقونه چې ورته لري seq_no! هغه څنګه؟ ښه، د مثال په توګه، سرور موږ ته یو څه لیږو، لیږو، او موږ پخپله خاموش یو، موږ یوازې د هغه پیغامونو ترلاسه کولو په اړه د خدماتو تایید پیغامونو سره ځواب ورکوو. په دې حالت کې، زموږ بهر ته تلونکي تاییدات به ورته بهرنۍ شمیره ولري. که تاسو د TCP سره آشنا یاست او فکر کوئ چې دا یو ډول لیونی ښکاري، مګر داسې ښکاري چې دا خورا وحشي نه وي، ځکه چې په TCP کې seq_no بدلون نه کوي، او تایید ته ځي seq_no بل اړخ - بیا زه د خپګان لپاره ګړندۍ یم. تاییدات MTProto ته راځي نه په seq_noلکه څنګه چې په TCP کې، مګر msg_id !

دا څه شی دی msg_idد دې ساحو تر ټولو مهم؟ د پیغام ځانګړی ID، لکه څنګه چې نوم معنی لري. دا د 64-bit شمیرې په توګه تعریف شوی، لږترلږه د پام وړ بټونه چې بیا یې د سرور نه - سرور جادو لري، او پاتې یې د یونیکس ټایم سټیمپ دی، د جزوی برخې په شمول، 32 بټونه کیڼ لور ته لیږدول شوي. هغوی. د وخت سټیمپ فی se (او پیغامونه د ډیری مختلف وختونو سره به د سرور لخوا رد شي). له دې څخه دا معلومه شوه چې، په عموم کې، دا یو پیژندونکی دی چې د پیرودونکي لپاره نړیوال دی. په داسې حال کې - په یاد ولرئ 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 تېروتنې (ښه، البته، د ځوابونو سیمانټیک ته درناوی نه کیږي، په ځینو ځایونو کې دوی په تصادفي ډول د کوډونو لخوا ویشل شوي)، او تار داسې ښکاري CAPITAL_LETTERS_AND_NUMBERS. د مثال په توګه، PHONE_NUMBER_OCCUPIED یا FILE_PART_X_MISSING. ښه، دا دی، تاسو لاهم دې کرښې ته یاست تجزیه کول. د مثال په توګه FLOOD_WAIT_3600 دا به پدې معنی وي چې تاسو باید یو ساعت انتظار وکړئ، او PHONE_MIGRATE_5د دې مخکینۍ سره د تلیفون شمیره باید په 5th DC کې ثبت شي. موږ یو ډول ژبه لرو، سمه ده؟ موږ د تار څخه دلیل ته اړتیا نلرو، منظم څرګندونې به وکړي، cho.

یوځل بیا ، دا د خدماتو پیغامونو پا pageه کې ندي ، مګر لکه څنګه چې دمخه د دې پروژې سره دود دی ، معلومات موندل کیدی شي د اسنادو په بله پاڼه کې. یا شک راپاروي. لومړی، وګورئ، د ټایپ کولو / پرتونو څخه سرغړونه - RpcError کې پانګونه کیدی شي RpcResult. ولې بهر نه؟ موږ څه په پام کې نه دي نیولي؟... په دې اساس، دا تضمین چیرته دی RpcError کیدای شي پانګونه ونه شي RpcResult، مګر مستقیم یا په بل ډول کې ځړول کیږي؟ دا نه لري req_msg_id ؟ ..

مګر راځئ چې د خدماتو پیغامونو ته دوام ورکړو. پیرودونکی ممکن په پام کې ونیسي چې سرور د اوږدې مودې لپاره فکر کوي، او داسې په زړه پورې غوښتنه وکړي:

rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;

دې ته درې احتمالي ځوابونه شتون لري، یوځل بیا د تایید میکانیزم سره یو ځای کول، ترڅو پوه شي چې دوی باید څه وي (او د ډولونو لیست څه شی دی چې په عمومي توګه تایید ته اړتیا نلري)، لوستونکی د کور کار په توګه پریښودل کیږي (یادونه: د ټیلیګرام ډیسټاپ سرچینو کې معلومات بشپړ ندي).

روږديتوب: د پیغام پوسټ حالتونه

په عموم کې، په 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… پاتې شمیرې چیرته دي، ټامي؟

په اسنادو کې راغلي:

نیت دا دی چې د error_code ارزښتونه ګروپ شوي (error_code >> 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 غوږونه چپه کیږي (موږ د بایټ ویکتور ته اړتیا درلوده، او د اینوم په ښکته دوه بټونو کې، او په زړو بټونو بیرغونو کې). خبره بل څه ده. ایا څوک پوهیږي چې ولې دا ټول په عمل کې دي په ریښتیني پیرودونکي کې اړین؟... له ستونزو سره، مګر تاسو کولی شئ یو څه ګټې تصور کړئ که چیرې یو څوک په ډیبګ کولو بوخت وي، او په متقابل حالت کې - له سرور څخه پوښتنه وکړئ چې څه او څنګه. مګر غوښتنې دلته بیان شوي تګ را تګ.

دا له دې څخه تعقیب کیږي چې هر اړخ باید نه یوازې کوډ کړي او پیغامونه واستوي، بلکې د دوی په اړه معلومات، د دوی ځوابونو او د نامعلوم وخت لپاره ذخیره کړي. اسناد د دې ځانګړتیاوو وخت یا عملي تطبیق نه بیانوي. هیڅ لاره نشته. هغه څه چې خورا حیرانتیا دي دا دي چې دوی په حقیقت کې د رسمي مراجعینو په کوډ کې کارول کیږي! په ښکاره ډول، دوی ته یو څه ویل شوي چې په خلاص اسنادو کې شامل ندي. د کوډ څخه پوهیدل د څه له پاره، نور د TL په قضیه کې دومره ساده ندي - دا (پرتله) منطقي جلا برخه نه ده ، مګر یوه ټوټه د غوښتنلیک جوړښت سره تړلې ده ، د بیلګې په توګه. د غوښتنلیک کوډ پوهیدو لپاره به ډیر وخت ته اړتیا ولري.

پینګونه او وختونه. کتارونه.

له هر څه څخه، که تاسو د سرور جوړښت (د بیک انډونو په اوږدو کې د غوښتنو ویش) په اړه اټکلونه په یاد ولرئ، یو څه ناڅاپه شی تعقیبوي - سره له دې چې د تحویلي ټولو تضمینونو سره سره چې په TCP کې (یا به معلومات ورکړل شوي وي، یا به تاسو ته خبر درکړل شي. بریک، مګر ډاټا به د ستونزې تر شیبې پورې وسپارل شي)، دا پخپله په MTProto کې تاییدوي - هیڅ تضمین نشته. سرور کولی شي په اسانۍ سره ستاسو پیغام له لاسه ورکړي یا وغورځوي، او د دې په اړه هیڅ شی نشي ترسره کیدی، یوازې د مختلفو ډولونو کرچونو د کټ کولو لپاره.

او تر ټولو لومړی - د پیغام کتارونه. ښه، د یو شی لپاره، هر څه د پیل څخه څرګند وو - یو نا تایید شوی پیغام باید زیرمه شي او بیا واستول شي. او څه وخت وروسته؟ او مکار هغه پیژني. شاید د روږدي خدماتو پیغامونه یو څه دا ستونزه د کرچونو سره حل کړي، ووایه چې د ټیلیګرام ډیسټاپ کې شاوخوا 4 کتارونه شتون لري چې ورته ورته دي (شاید نور ، لکه څنګه چې دمخه یادونه وشوه ، د دې لپاره تاسو اړتیا لرئ د دې کوډ او جوړښت ته ډیر جدي پام وکړئ؛ په ورته وخت کې وخت، موږ پوهیږو چې دا د نمونې په توګه نشي اخیستل کیدی، د MTProto سکیم څخه یو مشخص شمیر ډولونه پدې کې نه کارول کیږي).

ولې دا پیښیږي؟ شاید، د سرور پروګرام کونکي نشي کولی په کلستر کې اعتبار یقیني کړي، یا لږترلږه حتی په مخکینۍ بیلنس کې بفرینګ وکړي، او دا ستونزه یې پیرودونکي ته لیږدول. د نا امیدۍ له امله، ویسیلي هڅه وکړه چې یو بدیل اختیار پلي کړي، یوازې دوه کتارونو سره، د TCP څخه د الګوریتمونو په کارولو سره - سرور ته د RTT اندازه کول او د "کړکۍ" اندازه (په پیغامونو کې) د غیر منل شویو غوښتنو شمیر پورې اړه لري. دا ، د سرور بار اټکل کولو لپاره دومره ناڅاپه هورسټیک - زموږ څومره غوښتنې په ورته وخت کې ژاول کیدی شي او له لاسه نه ورکوي.

ښه، دا دی، تاسو پوهیږئ، سمه ده؟ که تاسو باید TCP بیا د پروتوکول په سر کې پلي کړئ چې په TCP باندې کار کوي ، دا خورا ضعیف ډیزاین شوی پروتوکول په ګوته کوي.

هو هو، ولې له یو څخه زیات قطار ته اړتیا ده، او په عموم کې، دا د هغه چا لپاره څه معنی لري چې د لوړې کچې API سره کار کوي؟ وګوره، تاسو یوه غوښتنه کوئ، تاسو یې سریالائز کړئ، مګر دا اکثرا ناشونې وي چې سمدستي یې واستوئ. ولې؟ ځکه چې ځواب به وي msg_id، کوم چې موقتي ويаزه یو لیبل یم، د هغه ټاکنه غوره ده چې د امکان تر حده ناوخته وځنډول شي - ناڅاپه سرور به دا رد کړي ځکه چې زموږ او د هغې تر منځ د وخت د توپیر له امله (البته، موږ کولی شو داسې کرچ جوړ کړو چې زموږ وخت له اوسني وخت څخه بدلوي. د سرور د ځوابونو څخه محاسبه شوي ډیلټا اضافه کولو سره د سرور وخت ته - رسمي پیرودونکي دا کار کوي، مګر دا طریقه خامه او د بفرینګ له امله ناسمه ده). نو کله چې تاسو د کتابتون څخه د محلي فنکشن زنګ سره غوښتنه وکړئ، پیغام د لاندې مرحلو څخه تیریږي:

  1. په ورته کتار کې پروت دی او د کوډ کولو په تمه دی.
  2. ټاکل شوی msg_id او پیغام بل کتار ته لاړ - ممکنه لیږل؛ ساکټ ته لیږل.
  3. a) سرور ځواب ورکړ MsgsAck - پیغام استول شوی و، موږ یې د "نور کتار" څخه حذف کوو.
    ب) یا برعکس، هغه یو څه نه خوښوي، هغه د بدماش ځواب ورکړ - موږ د "بل کتار" څخه بیا لیږو
    c) هیڅ نه پوهیږي، دا اړینه ده چې پیغام له بل کتار څخه بیا واستول شي - مګر دا معلومه نده چې کله.
  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 ثانیو کې یو ځل واستوي، د بیلګې په توګه، دا ممکن د 75 ثانیو سره مساوي disconnect_delay تنظیم کړي.

ایا ستاسو له ذهن څخه وتلی دی؟! په 60 ثانیو کې، اورګاډی سټیشن ته ننوځي، ښکته شي او مسافرین پورته کړي، او بیا به په تونل کې اړیکه له لاسه ورکړي. په 120 ثانیو کې ، پداسې حال کې چې تاسو شاوخوا ځړول یاست ، هغه به بل ته راشي ، او اړیکه به ډیری احتمال مات شي. ښه، دا روښانه ده چې پښې له کوم ځای څخه وده کوي - "ما غږ واورېد، مګر زه نه پوهیږم چې دا چیرته دی"، د ناګل الګوریتم او TCP_NODELAY اختیار شتون لري، کوم چې د متقابل کار لپاره ټاکل شوی و. مګر، بخښنه، د دې اصلي ارزښت ځنډول - 200 ملیثانیې که تاسو واقعیا غواړئ یو څه ورته انځور کړئ او په ممکنه جوړه کڅوړو کې خوندي کړئ - ښه ، لږترلږه د 5 ثانیو لپاره یې بند کړئ ، یا هرڅه چې د پیغام وخت پای ته رسیدلی "کاروونکی ټایپ کوي ..." اوس مساوي دی. خو نور نه.

او په نهایت کې ، پینګونه. دا د TCP اتصال ژوندیتوب چیک کول دي. دا مسخره ده ، مګر شاوخوا 10 کاله دمخه ما زموږ د پوهنځي د میلمستون د میسنجر په اړه یو انتقادي متن لیکلی و - هلته لیکوالانو هم د پیرودونکي څخه سرور پینګ کړی ، او برعکس. مګر د دریم کال زده کونکي یو شی دی، او نړیوال دفتر بل دی، سمه ده؟ ..

لومړی، یو کوچنی تعلیمي پروګرام. د TCP پیوستون، د پاکټ تبادلې په نشتوالي کې، د اونیو لپاره ژوند کولی شي. دا دواړه ښه او بد دي، د هدف پورې اړه لري. ښه ، که تاسو د سرور سره د SSH اتصال خلاص کړی و ، نو تاسو له خپل کمپیوټر څخه پورته شو ، د بریښنا روټر یې ریبوټ کړ ، خپل ځای ته راستون شو - د دې سرور له لارې سیشن مات نه شو (هیڅ ټایپ نه کړ ، هیڅ پاکټونه شتون نلري) ، اسانه دا خراب دی که چیرې په سرور کې زرګونه پیرودونکي شتون ولري، هر یو یې سرچینې اخلي (هیلو پوسټګریس!)، او د پیرودونکي کوربه ممکن ډیر وخت دمخه ریبوټ کړی وي - مګر موږ به پدې اړه نه پوهیږو.

د چیٹ/IM سیسټمونه د بل لپاره د دویمې قضیې سره تړاو لري، اضافي دلیل - آنلاین حالتونه. که چیرې کاروونکي "بند شوی" وي، نو اړینه ده چې د هغې په اړه خپل مخاطبینو ته خبر ورکړي. که نه نو، یوه تېروتنه به وي چې د جابر جوړونکي یې کړي (او د 20 کلونو لپاره یې اصلاح کړي) - کارونکي یې منحل کړي، مګر دوی هغه ته پیغامونو لیکلو ته دوام ورکوي، پدې باور چې هغه آنلاین دی (کوم چې په دې څو دقیقو کې په بشپړ ډول ورک شوی و. وقفه کشف شوه). نه، د TCP_KEEPALIVE اختیار، کوم چې ډیری خلک چې نه پوهیږي چې د TCP ټیمر څنګه کار کوي، په هر ځای کې پاپ کیږي (د وحشي ارزښتونو لکه لسګونه ثانیو په ترتیبولو سره)، دلته به مرسته ونکړي - تاسو اړتیا لرئ ډاډ ترلاسه کړئ چې نه یوازې د OS کارنل. د کارونکي ماشین ژوندی دی، مګر په نورمال ډول کار کوي، د ځواب ورکولو توان لري، او پخپله غوښتنلیک (ایا تاسو فکر کوئ چې دا کنګل نشي کولی؟ په اوبنټو 18.04 کې د ټیلیګرام ډیسټاپ زما لپاره په مکرر ډول ټکر شوی).

له همدې امله تاسو باید پینګ وکړئ سرور مراجع، او نه برعکس - که چیرې پیرودونکي دا وکړي، کله چې اړیکه مات شي، پینګ به ونه سپارل شي، هدف نه دی ترلاسه شوی.

او موږ په ټیلیګرام کې څه ګورو؟ هرڅه بالکل برعکس دي! ښه، i.e. په رسمي توګه، البته، دواړه خواوې کولی شي یو بل پینګ کړي. په عمل کې، پیرودونکي یو کرچ کاروي ping_delay_disconnect، کوم چې په سرور کې ټایمر کاک کوي. ښه، بخښنه، دا د پیرودونکي سوداګرۍ نه دی چې پریکړه وکړي چې څومره وخت غواړي هلته پرته له پینګ ژوند وکړي. سرور، د هغې د بار پر بنسټ، ښه پوهیږي. مګر، البته، که تاسو د سرچینو لپاره بخښنه نه کوئ، نو بد Pinocchio پخپله دي، او کرچ به ښکته راشي ...

دا باید څنګه ډیزاین شوی وي؟

زه باور لرم چې پورتني حقایق په ښکاره ډول د کمپیوټري شبکو د ټرانسپورټ (او ټیټ) کچې په برخه کې د ټیلیګرام / VKontakte ټیم خورا لوړ وړتیا او په اړوندو چارو کې د دوی ټیټ وړتیا په ګوته کوي.

ولې دا دومره پیچلې شوه، او څنګه کولی شي د ټیلیګرام معماران د اعتراض هڅه وکړي؟ حقیقت دا دی چې دوی هڅه کړې یوه غونډه جوړه کړي چې د TCP پیوستون ماتولو څخه ژوندي پاتې شي، دا هغه څه دي چې موږ یې اوس نه دي وړاندې کړي، موږ به وروسته وړاندې کړو. دوی شاید د UDP ټرانسپورټ رامینځته کولو هڅه هم کړې وي ، که څه هم دوی له ستونزو سره مخ شوي او دا یې پریښوده (له همدې امله اسناد خالي دي - د ویاړ کولو لپاره هیڅ شتون نلري). مګر د پوهیدو نشتوالي له امله چې څنګه په عمومي ډول شبکې او په ځانګړي ډول TCP کار کوي ، چیرې چې تاسو په دې تکیه کولی شئ ، او چیرې چې تاسو اړتیا لرئ دا پخپله ترسره کړئ (او څنګه) ، او دا د کریپټوګرافي سره یوځای کولو هڅه کوي "د دوه څخه یو شاټ مرغۍ د یوې تیږې سره "- داسې یو جسد بهر شو.

دا باید څنګه وی؟ د دې حقیقت پر بنسټ msg_id یو مهال ویش دی چې په کریپټوګرافیک ډول اړین دی چې د بیا چلولو بریدونو مخه ونیسي، دا یوه تېروتنه ده چې د یو ځانګړي پیژندونکي فعالیت سره ضمیمه کړي. له همدې امله، پرته له دې چې د اوسني جوړښت په پراخه توګه بدلون ومومي (کله چې د تازه معلوماتو موضوع جوړه شي، دا د دې لړۍ د پوستونو بلې برخې لپاره د لوړې کچې API موضوع ده)، یو باید:

  1. هغه سرور چې د مراجعینو سره د TCP پیوستون لري مسؤلیت په غاړه اخلي - که تاسو له ساکټ څخه تخفیف کړی وي، مهرباني وکړئ اعتراف وکړئ، پروسس یا بیرته راستانه کړئ، هیڅ تاوان. بیا تایید د ids ویکتور نه دی، مګر په ساده ډول "وروستی ترلاسه شوی seq_no" - یوازې یو شمیره، لکه څنګه چې په TCP کې (دوه شمیرې - ستاسو خپل seq او تایید شوی). موږ تل په ناسته کې یو، ایا موږ نه یو؟
  2. د بیا ځلي بریدونو مخنیوي لپاره مهال ویش یو جلا ساحه کیږي، یو لا نانس. چک شوی، مګر نور هیڅ اغیزه نلري. بس او uint32 - که زموږ مالګه لږترلږه هره نیمه ورځ بدله شي، موږ کولی شو د اوسني وخت د بشپړې برخې ټیټې برخې ته 16 بټونه تخصیص کړو، پاتې نور - د ثانیې برخې برخې ته (لکه څنګه چې اوس دی).
  3. بیرته راګرځیدل msg_id په ټوله کې - په پس منظر کې د غوښتنو توپیر کولو له نظره، لومړی، د پیرودونکي id، او دویم، د ناستې ID، او دوی سره یوځای کول شتون لري. په دې اساس، د غوښتنې پیژندونکي په توګه، یوازې یو کافی دی seq_no.

همدارنګه غوره اختیار نه دی، یو بشپړ تصادفي کولی شي د پیژندونکي په توګه خدمت وکړي - دا دمخه د لوړې کچې API کې ترسره کیږي کله چې پیغام لیږل کیږي. دا به غوره وي چې معمار له نسبي څخه مطلق ته بیا جوړ کړئ ، مګر دا د بلې برخې موضوع ده ، نه دا پوسټ.

API؟

تادام! نو، د درد او دردونو څخه ډکې لارې ته د رسیدو سره، موږ په پای کې وتوانیدو چې سرور ته کومې غوښتنې واستوو او دوی ته کوم ځوابونه ترلاسه کړو، او همدارنګه د سرور څخه تازه معلومات ترلاسه کړو (د غوښتنې په ځواب کې نه، مګر دا موږ ته پخپله لیږو، لکه PUSH، که څوک دومره روښانه وي).

پاملرنه، اوس به په مقاله کې یوازې د پرل مثال وي! (د هغو کسانو لپاره چې له نحو سره بلد نه وي، د برکت لپاره لومړی دلیل د شیانو د معلوماتو جوړښت دی، دویم یې ټولګی دی):

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' )
};

هو، په ځانګړې توګه د سپیلر لاندې نه - که تاسو دا نه وي لوستلی، لاړ شئ او دا یې وکړئ!

اوه، وای ~~… دا څه ښکاري؟ یو څه ډیر پیژندل شوی ... شاید دا په JSON کې د یو ځانګړي ویب API ډیټا جوړښت وي ، پرته لدې چې ټولګي د شیانو سره وصل شوي وي؟ ..

نو دا معلومه شوه ... دا څه دي، ملګري؟ .. ډیره هڅه - او موږ د ویب پروګرامرانو په ځای کې د آرام کولو لپاره ودرول. یوازې پیل کول؟.. ایا یوازې JSON په HTTPS کې اسانه نه وي؟! او په بدل کې مو څه ترلاسه کړل؟ ایا دا هڅې د ارزښت وړ وې؟

راځئ ارزونه وکړو چې TL+MTProto موږ ته څه راکړي او کوم بدیلونه ممکن دي. ښه، د HTTP غوښتنې ځواب یو بد فټ دی، مګر لږترلږه د TLS په سر کې یو څه؟

کمپیکٹ سریال کول. د دې ډاټا جوړښت ته په کتلو سره، JSON ته ورته، دا په یاد ولرئ چې د دې بائنری ډولونه شتون لري. راځئ چې MsgPack په کافي توګه د نه توزیع کېدونکي په توګه په نښه کړو، مګر دلته شتون لري، د بیلګې په توګه، CBOR - په لاره کې، معیار چې په کې تشریح شوی. RFC 7049. دا د دې حقیقت لپاره د پام وړ دی چې دا تعریف کوي ټاګونهد تمدید میکانیزم په توګه، او په منځ کې دمخه معیاري شوی دلته دي:

  • 25 + 256 - د لاین شمیرې حوالې سره د نقل لینونو ځای په ځای کول ، دا ډول ارزانه کمپریشن میتود
  • 26 - سیریل شوی پرل اعتراض د ټولګي نوم او جوړونکي دلیلونو سره
  • 27 - د ډول نوم او جوړونکي دلیلونو سره د ژبې څخه خپلواک څیز سریال شوی

ښه، ما هڅه وکړه چې ورته ډیټا په TL او CBOR کې د تارونو او شیانو بسته کولو سره فعاله کړم. پایله د میګابایټ څخه د CBOR په ګټه توپیر پیل شو:

cborlen=1039673 tl_len=1095092

او همداسې، پایله: د پام وړ ساده فارمیټونه شتون لري چې د مطابقت وړ موثریت سره د همغږي ناکامۍ یا نامعلوم پیژندونکي ستونزې سره مخ ندي.

د ګړندي اړیکې رامینځته کول. دا پدې مانا ده چې د بیا پیوستون وروسته صفر RTT (کله چې کیلي دمخه یوځل رامینځته شوې وي) - د لومړي MTProto پیغام څخه پلي کیږي ، مګر د یو څه خوندیتوب سره - دوی ورته مالګې ته رسیدلي ، غونډه خرابه شوې نه وه ، او داسې نور. TLS موږ ته په بدل کې څه وړاندیز کوي؟ اړونده اقتباس:

کله چې په TLS کې PFS کاروئ، د TLS ناستې ټکټونه (RFC 5077) پرته له دې چې کیلي له سره خبرې وکړي او په سرور کې د کلیدي معلوماتو ذخیره کولو پرته د کوډ شوي ناستې بیا پیل کول. کله چې لومړی اتصال خلاص کړئ او کیلي تولید کړئ ، سرور د پیوستون حالت کوډ کوي او پیرودونکي ته یې لیږي (د سیشن ټیکټ په شکل کې). په دې اساس، کله چې پیوستون بیا پیل شي، پیرودونکي د سیشن ټیکټ لیږي چې د نورو شیانو په مینځ کې، د سیشن کیلي بیرته سرور ته. ټیکټ پخپله د لنډمهاله کیلي (د ناستې ټکټ کیلي) سره کوډ شوی دی، کوم چې په سرور کې زیرمه شوی او باید ټولو فرنټ اینډ سرورونو ته وویشل شي چې په کلستر شوي حلونو کې SSL اداره کوي.[10] په دې توګه، د سیشن ټیکټ معرفي کول د PFS څخه سرغړونه کولی شي که چیرې د لنډمهاله سرور کلیدونو سره جوړجاړی وشي، د بیلګې په توګه، کله چې دوی د اوږدې مودې لپاره زیرمه شوي وي (OpenSSL، nginx، Apache په ډیفالټ ډول دوی د پروګرام د چلولو ټول وخت لپاره ذخیره کوي؛ مشهور سایټونه کیلي د څو ساعتونو لپاره وکاروئ، تر ورځو پورې).

دلته RTT صفر نه دی، تاسو اړتیا لرئ لږترلږه ClientHello او ServerHello تبادله کړئ، له هغې وروسته، د بشپړ شوي سره یوځای، پیرودونکي کولی شي مخکې له دې ډاټا واستوي. مګر دلته دا باید په یاد ولرئ چې موږ ویب نه لرو، د هغې د نویو پرانیستل شویو اړیکو سره، مګر یو میسنجر، چې ډیری وختونه یو یا ډیر یا لږ اوږد وي، د ویب پاڼو لپاره نسبتا لنډې غوښتنې - هرڅه دي. دننه ملټي پلیکس. دا دی، دا خورا د منلو وړ دی، که موږ د یوې خورا خراب فرعي برخې سره مخ نه شو.

بل څه هېر کړي؟ په نظرونو کې ولیکئ.

نور بیا!

د پوسټونو د دې لړۍ په دویمه برخه کې به موږ د تخنیکي مسلو پرځای تنظیمي مسلې په پام کې ونیسو - چلند، نظریه، انٹرفیس، د کاروونکو په وړاندې چلند، او داسې نور. په هرصورت، د تخنیکي معلوماتو پر بنسټ چې دلته وړاندې شوي.

دریمه برخه به د تخنیکي برخې / پراختیا تجربې تحلیل ته دوام ورکړي. تاسو به په ځانګړې توګه زده کړئ:

  • د TL ډولونو ډولونو سره د پانډمونیم دوام
  • د چینلونو او سپر ګروپونو په اړه نامعلوم شیان
  • د ډیالوګ په پرتله د لیست څخه بد دی
  • د مطلق او نسبي پیغام پته په اړه
  • د عکس او عکس تر مینځ توپیر څه دی
  • څنګه ایموجي د ایټالیکي متن سره مداخله کوي

او نورې بزکشۍ! ولاړ شه!

سرچینه: www.habr.com

Add a comment