ٽيليگرام جي پروٽوڪول ۽ تنظيمي طريقن جي تنقيد. حصو 1، ٽيڪنيڪل: شروع کان ڪلائنٽ لکڻ جو تجربو - TL، MT

تازو، پوسٽون ته ٽيليگرام ڪيترو سٺو آهي، ڊورو برادرز نيٽ ورڪ سسٽم ٺاهڻ ۾ ڪيترا شاندار ۽ تجربا آهن، وغيره گهڻو ڪري Habré تي ظاهر ٿيڻ شروع ٿي ويا آهن. ساڳئي وقت، تمام ٿورا ماڻهو حقيقت ۾ پاڻ کي ٽيڪنيڪل ڊيوائس ۾ وڪوڙي ويا آهن - گهڻو ڪري اهي ڪافي سادو استعمال ڪندا آهن (۽ MTProto کان بلڪل مختلف) JSON-based Bot API، ۽ عام طور تي صرف قبول ڪندا آهن. ايمان تي اهي سڀئي ساراهه ۽ پي آر جيڪي رسول جي چوڌاري گردش ڪن ٿا. لڳ ڀڳ ڏيڍ سال اڳ، منهنجي ساٿي اين پي او ايچيلون واسيلي (بدقسمتي سان، هن جو اڪائونٽ Habré تي مسودو سان گڏ ڊهي ويو) پرل ۾ شروع کان پنهنجي ٽيليگرام ڪلائنٽ لکڻ شروع ڪيو، ۽ بعد ۾ انهن لائينن جو ليکڪ شامل ٿيو. ڇو پرل، ڪجهه فوري طور تي پڇندا؟ ڇو ته ٻين ٻولين ۾ اهڙا پروجيڪٽ اڳ ۾ ئي موجود آهن، حقيقت ۾ اها ڳالهه ناهي، اتي ڪا ٻي ٻولي ٿي سگهي ٿي ختم ٿيل لائبريري، ۽ ان جي مطابق ليکڪ کي سڀني طريقي سان وڃڻ گهرجي شروعات کان. ان کان علاوه، cryptography اهڙي شيء آهي - اعتماد، پر تصديق ڪريو. حفاظتي مرڪوز پراڊڪٽ سان، توهان صرف وينڊر جي تيار ڪيل لائبريري تي ڀروسو نٿا ڪري سگهو ۽ ان تي انڌو يقين رکو (جڏهن ته، اهو هڪ موضوع آهي ٻئي حصي ۾ وڌيڪ لاءِ). هن وقت، لائبريري "وچولي" سطح تي تمام سٺو ڪم ڪري ٿي (توهان کي ڪنهن به API درخواستون ڪرڻ جي اجازت ڏئي ٿي).

تنهن هوندي، پوسٽن جي هن سلسلي ۾ گهڻو ڪجهه cryptography ۽ رياضي نه هوندو. پر ان ۾ ٻيا به ڪيترائي ٽيڪنيڪل تفصيل ۽ اڏاوتي ڪچھريون هونديون (اهو انهن لاءِ به ڪارائتو هوندو، جيڪي نه لکندا، پر ڪنهن به ٻوليءَ ۾ لائبريري استعمال ڪندا). تنهن ڪري، بنيادي مقصد شروع ڪرڻ کان ڪلائنٽ کي لاڳو ڪرڻ جي ڪوشش ڪئي وئي سرڪاري دستاويز موجب. اهو آهي، فرض ڪريو ته سرڪاري گراهڪ جو سورس ڪوڊ بند آهي (ٻيهر، ٻئي حصي ۾، اسان وڌيڪ تفصيل سان ظاهر ڪنداسين ته هي ڇا آهي. ائين ٿيندو آهي تنهن ڪري)، پر، جيئن پراڻن ڏينهن ۾، مثال طور، اتي هڪ معيار آهي جهڙوڪ آر ايف سي - ڇا اهو ممڪن آهي ته ڪلائنٽ کي اڪيلو وضاحتن جي مطابق لکڻ، "بغير جڙيل" ذريعو تي، جيتوڻيڪ سرڪاري (ٽيليگرام ڊيسڪ ٽاپ، موبائل) ، جيتوڻيڪ غير رسمي ٽيليٿون؟

جواب:

دستاويز ... ڇا اهو آهي؟ ڇا اهو سچ آهي؟..

هن آرٽيڪل لاءِ نوٽس جا ٽڪرا گڏ ٿيڻ شروع ٿيا گذريل اونهاري ۾. هي سڀ وقت سرڪاري سائيٽ تي https://core.telegram.org دستاويز ليئر 23 جي طور تي هو، يعني 2014 ۾ ڪٿي بيٺو (ياد رکو، ان وقت تائين اڃا تائين چينل نه هئا؟). يقينن، نظريي ۾، اهو ممڪن بڻائڻ گهرجي ته 2014 ۾ انهي وقت ڪارڪردگي سان هڪ ڪلائنٽ لاڳو ڪرڻ. پر هن حالت ۾ به، دستاويز هو، پهريون، نامڪمل، ۽ ٻيو، هنڌن تي اهو پاڻ ۾ تضاد آهي. ٿورڙو هڪ مهينو اڳ، سيپٽمبر 2019 ۾، اهو هو حادثي طور تي اهو معلوم ٿيو ته سائيٽ وٽ دستاويز جي هڪ وڏي تازه ڪاري آهي، مڪمل طور تي تازو پرت 105 لاء، هڪ نوٽ سان ته هاڻي هر شي کي ٻيهر پڙهڻ جي ضرورت آهي. درحقيقت، ڪيترائي مضمون تبديل ڪيا ويا آهن، پر ڪيترائي اڻڄاتل رهجي ويا آهن. تنهن ڪري، جڏهن دستاويز جي باري ۾ هيٺ ڏنل تنقيد کي پڙهو، توهان کي ذهن ۾ رکڻ گهرجي ته انهن مان ڪجهه شيون هاڻي لاڳاپيل نه آهن، پر ڪجهه اڃا تائين ڪافي آهن. سڀ کان پوء، جديد دنيا ۾ 5 سال صرف تمام گهڻو نه آهي، پر تمام تمام گهڻو. ان وقت کان وٺي (خاص طور تي جيڪڏهن توهان ان وقت کان رد ٿيل ۽ جيئرو ڪيل جيوچيٽس تي ڌيان نه ڏيو)، اسڪيم ۾ API طريقن جو تعداد هڪ سؤ کان وڌي ويو آهي ٻه سئو پنجاهه کان وڌيڪ!

توهان هڪ نوجوان ليکڪ جي حيثيت ۾ ڪٿي شروع ڪيو؟

اهو مسئلو ناهي ته توهان شروع کان لکندا آهيو يا استعمال ڪريو، مثال طور، تيار ڪيل لائبريريون وانگر Python لاءِ ٽيليٿون يا PHP لاءِ ميڊلينڪنهن به صورت ۾، توهان کي پهرين ضرورت پوندي توهان جي درخواست رجسٽر ڪريو - پيرا ميٽرز حاصل ڪريو api_id и api_hash (جيڪي VKontakte API سان ڪم ڪن ٿا فوري طور تي سمجھن ٿا) جنهن جي ذريعي سرور ايپليڪيشن جي سڃاڻپ ڪندو. هي ڪيو قانوني سببن جي ڪري، پر اسان ان بابت وڌيڪ ڳالهائينداسين ته لائبريري جا ليکڪ ان کي ٻئي حصي ۾ شايع ڇو نٿا ڪري سگهن. ٿي سگهي ٿو توهان ٽيسٽ جي قيمتن سان مطمئن ٿي ويندا، جيتوڻيڪ اهي تمام محدود آهن - حقيقت اها آهي ته هاڻي توهان پنهنجي نمبر تي رجسٽر ڪري سگهو ٿا صرف هڪ ايپليڪيشن، تنهنڪري جلدي نه ڪريو.

هاڻي، ٽيڪنيڪل نقطي نظر کان، اسان کي حقيقت ۾ دلچسپي وٺڻ گهرجي ته رجسٽريشن کان پوء اسان کي ٽيليگرام کان نوٽيفڪيشن حاصل ڪرڻ گهرجي دستاويزن، پروٽوڪول، وغيره جي تازه ڪاري بابت. اهو آهي، هڪ اهو سمجهي سگهي ٿو ته ڊاکن سان سائيٽ صرف "اسڪور" ڪئي وئي هئي ۽ خاص طور تي انهن سان ڪم ڪرڻ جاري رکي، جيڪي گراهڪ ٺاهڻ شروع ڪيو، ڇاڪاڻ ته. اهو آسان آهي. پر نه، اهڙو ڪجهه به نظر نه آيو، نه ڪا خبر آئي.

۽ جيڪڏهن توهان شروع کان لکندا آهيو، پوء حاصل ڪيل پيٽرولن جو استعمال اصل ۾ اڃا پري آهي. جيتوڻيڪ https://core.telegram.org/ ۽ انھن بابت ڳالھيون پھريون شروعات ڪرڻ ۾، حقيقت ۾، توھان کي پھريون ڀيرو لاڳو ڪرڻو پوندو MTProto پروٽوڪول - پر جيڪڏهن توهان يقين ڪيو OSI ماڊل مطابق ترتيب پروٽوڪول جي عام وضاحت جي صفحي جي آخر ۾، پوء مڪمل طور تي بيڪار.

حقيقت ۾، ٻئي MTProto کان اڳ ۽ بعد ۾، هڪ ئي وقت ۾ ڪيترن ئي سطحن تي (جيئن ته OS ڪنيل ۾ ڪم ڪندڙ پرڏيهي نيٽ ورڪرز چون ٿا، پرت جي خلاف ورزي)، هڪ وڏو، دردناڪ ۽ خوفناڪ موضوع رستي ۾ اچي ويندو ...

بائنري سيريلائيزيشن: TL (قسم جي ٻولي) ۽ ان جي اسڪيم، ۽ پرت، ۽ ٻيا ڪيترائي خوفناڪ لفظ

هي موضوع، حقيقت ۾، ٽيليگرام جي مسئلن جي ڪنجي آهي. ۽ اهڙا ڪيترائي خوفناڪ لفظ هوندا جيڪڏهن توهان ان کي ڳولڻ جي ڪوشش ڪندا.

تنهن ڪري، اسڪيم. جيڪڏھن توھان کي ھي لفظ ياد آھي ته چئو، 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، long، etc.) جيئن ته ڪجھه ابتدائي طور تي سوال نه اٿاريندو آهي - آخر ۾ انهن کي دستي طور تي لاڳو ڪيو وڃي - مثال طور، اچو ته انهن مان حاصل ڪرڻ جي ڪوشش ڪريون. ویکٹر. اهو آهي، حقيقت ۾، صف، جيڪڏهن توهان نتيجن واري شين کي انهن جي صحيح نالن سان سڏيندا آهيو.

پر ان کان اڳ

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---، پوءِ نحو ساڳيو رهندو، پر معنيٰ مختلف هوندي: ڪنسٽرڪٽر آر پي سي فنڪشن جو نالو بڻجي ويندو، فيلڊ پيرا ميٽرز بڻجي ويندا (چڱو، اهو آهي، اهو بلڪل ساڳيو ئي ڍانچي رهندو، جيئن هيٺ بيان ڪيو ويو آهي، ان جي صرف معنيٰ ڏني ويندي) ۽ ”پوليمورفڪ ٽائپ“ موٽايل نتيجن جو قسم آهي. سچ، اهو اڃا تائين پوليمورفڪ رهندو - صرف سيڪشن ۾ بيان ڪيو ويو آهي ---types---، ۽ هي تعمير ڪندڙ نه سمجهيو ويندو. انهن جي دليلن جي ذريعي سڏايل افعال جي اوورلوڊ کي ٽائپ ڪريو، يعني. ڪجهه سببن لاءِ، ساڳئي نالي سان ڪيترائي فنڪشن پر هڪ مختلف دستخط، جيئن C++ ۾، TL ۾ مهيا نه ڪيا ويا آهن.

ڇو "ٺاهيندڙ" ۽ "پوليمورفڪ" جيڪڏهن اهو OOP نه آهي؟ يقينن، حقيقت ۾، اهو آسان ٿيندو ته ڪنهن جي لاء ان جي باري ۾ سوچڻ OOP جي لحاظ کان - هڪ پوليمورفڪ قسم هڪ تجريدي طبقي وانگر، ۽ تعمير ڪندڙ ان جي سڌي نسل وارا طبقا آهن، ان کان علاوه. final ڪيترن ئي ٻولين جي اصطلاحن ۾. حقيقت ۾، يقينا، هتي هڪجهڙائي OO پروگرامنگ ٻولين ۾ حقيقي اوور لوڊ ٿيل تعميراتي طريقن سان. جيئن ته هتي صرف ڊيٽا جي جوڙجڪ آهن، اتي ڪي به طريقا نه آهن (جيتوڻيڪ هيٺ ڏنل ڪمن ۽ طريقن جي وضاحت سر ۾ مونجهارو پيدا ڪرڻ جي قابل آهي ته اهي ڇا آهن، پر اهو ڪنهن ٻئي جي باري ۾ آهي) - توهان هڪ تعمير ڪندڙ جي طور تي سمجهي سگهو ٿا. جنهن مان قدر تعمير ڪيو پيو وڃي ٽائپ ڪريو جڏهن بائيٽ جو وهڪرو پڙهو.

اهو ڪيئن ٿو ٿئي؟ deserializer، جيڪو هميشه 4 بائيٽ پڙهي ٿو، قدر ڏسي ٿو 0xcrc32 - ۽ سمجهي ٿو ته اڳتي ڇا ٿيندو field1 قسم سان int، i.e. پڙهي ٿو بلڪل 4 بائيٽ، هن اوورلينگ فيلڊ تي قسم سان PolymorType پڙهو ڏسندو آهي 0x2crc32 ۽ سمجھي ٿو ته ٻه شعبا اڳتي آھن، پھريون long، تنهنڪري اسان 8 بائيٽ پڙهون ٿا. ۽ پوء ٻيهر هڪ پيچيده قسم، جيڪو ساڳئي طريقي سان ختم ڪيو ويو آهي. مثال طور، 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 افعال منفرد طور تي طئي ڪرڻ لاءِ ته ڪهڙي قسم جو (ڊي) سيريل ڪيو پيو وڃي. هتي اسان کي ٽڪر جي مسئلي سان منهن ڏيڻو پيو - ۽ نه، امڪان 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 منتقلي؟

هي هڪ بيڪار نظرياتي سوال ناهي - تصور ڪريو ته توهان گروپ استعمال ڪندڙن جي هڪ فهرست حاصل ڪريو، جن مان هر هڪ جي سڃاڻپ، پهريون نالو، آخري نالو آهي - موبائل ڪنيڪشن تي منتقل ڪيل ڊيٽا جي مقدار ۾ فرق اهم ٿي سگهي ٿو. اها ٽيليگرام سيريلائيزيشن جي تاثير آهي جيڪا اسان کي اشتهار ڏني وئي آهي.

سو…

ویکٹر، جنهن جو اندازو نه لڳائي سگهجي

جيڪڏھن توھان ڪوشش ڪندا ته combinators جي تفصيلي صفحا ۽ اٽڪل، توھان ڏسندؤ ته ھڪڙو ویکٹر (۽ جيتوڻيڪ ھڪڙو ميٽرڪس) رسمي طور تي ٽوپلز ذريعي ڪيترن ئي شيٽ کي گھٽائڻ جي ڪوشش ڪري رھيو آھي. پر آخر ۾ انهن کي ڇڪايو وڃي ٿو، آخري مرحلو ڇڏي ڏنو ويو آهي، ۽ ویکٹر جي تعريف صرف ڏني وئي آهي، جيڪو پڻ هڪ قسم سان پابند ناهي. هتي ڪهڙو معاملو آهي؟ ٻولين ۾ پروگرامنگخاص طور تي فنڪشنل، ان جي جوڙجڪ کي بار بار بيان ڪرڻ بلڪل عام آهي - ان جي سست تشخيص سان گڏ ڪرڻ وارو سڀ ڪجهه سمجهي سگهندو ۽ اهو ڪندو. ٻوليءَ ۾ ڊيٽا سيريلائيزيشن پر ڪارڪردگي جي ضرورت آهي: اهو صرف بيان ڪرڻ لاء ڪافي آهي فهرست، i.e. ٻن عنصرن جو هڪ ڍانچو - پهريون هڪ ڊيٽا عنصر آهي، ٻيو آهي ساڳيو ڍانچي پاڻ يا دم لاءِ خالي جاءِ (پيڪ (cons) Lisp ۾). پر اهو واضح طور تي گهربل هوندو هر هڪ جو عنصر اضافي طور تي 4 بائيٽ خرچ ڪري ٿو (TL جي صورت ۾ CRC32) ان جي قسم کي بيان ڪرڻ لاء. اهو هڪ صف بيان ڪرڻ آسان آهي مقرر سائيز، پر اڳئين اڻڄاتل ڊگھائي جي صف جي صورت ۾، اسان بند ڪريون ٿا.

تنهن ڪري جيئن ته TL توهان کي ویکٹر ڪڍڻ جي اجازت نٿو ڏئي، ان کي پاسي ۾ شامل ڪرڻو پوندو. آخرڪار دستاويز چوي ٿو:

سيريلائيزيشن هميشه هڪ ئي ڪنسٽرڪٽر ”ویکٹر“ استعمال ڪري ٿي (const 0x1cb5c415 = crc32(“vector t:Type # [ t] = Vector t”) جيڪو ٽائپ جي متغير جي مخصوص قدر تي منحصر ناهي.

اختياري پيٽرولر جي قيمت ٽي سيريلائيزيشن ۾ شامل نه آهي ڇو ته اهو نتيجو قسم مان نڪتل آهي (هميشه deserialization کان اڳ ڄاڻايل آهي).

هڪ ويجهي نظر وٺو: vector {t:Type} # [ t ] = Vector t - پر اڃان وصف پاڻ نه ٿو چوي ته پهريون نمبر ويڪٽر جي ڊيگهه جي برابر هجڻ گهرجي! ۽ اهو ڪٿي به پيروي نٿو ڪري. اهو هڪ ڏنو ويو آهي جيڪو توهان کي ذهن ۾ رکڻ ۽ توهان جي هٿن سان لاڳو ڪرڻ جي ضرورت آهي. ٻي جاءِ تي، دستاويز پڻ ايمانداري سان بيان ڪري ٿو ته قسم جعلي آهي:

Vector t پوليمورفڪ pseudotype هڪ "قسم" آهي جنهن جي قيمت ڪنهن به قسم جي قدرن جو هڪ تسلسل آهي، يا ته باڪس ٿيل يا بيئر.

... پر ان تي ڌيان نه ٿو ڏئي. جڏهن توهان، رياضي (شايد توهان کي يونيورسٽي جي ڪورس کان به خبر هجي) جي طويل وڇوڙي تان ٿڪجي پيا، سکور ڪرڻ جو فيصلو ڪيو ۽ ڏسو ته اصل ۾ ان سان ڪيئن ڪم ڪجي، اهو تاثر توهان جي ذهن ۾ رهندو: هتي سنجيده رياضي تي ٻڌل آهي. ، واضح طور تي سٺا ماڻهو (ٻه رياضي دان - ACM جو فاتح)، ۽ نه صرف ڪنهن کي. مقصد - تقسيم ڪرڻ - حاصل ڪيو ويو آهي.

رستي ۾، انگ بابت. ياد ڪرڻ # اهو هڪ مترادف آهي natقدرتي نمبر:

هتي قسم جا اظهار آهن (ٽائيپ ايڪسپر) ۽ عددي اظهار (nat-expr). تنهن هوندي به، اهي ساڳيء طرح بيان ڪيا ويا آهن.

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

پر گرامر ۾ اهي ساڳيا بيان ڪيا ويا آهن، يعني. اهو فرق ٻيهر ياد رکڻ گهرجي ۽ هٿ سان عمل ۾ رکڻ گهرجي.

خير، ها، ٽيمپليٽ جا قسم (vector<int>, vector<User>هڪ عام سڃاڻپ ڪندڙ آهي (#1cb5c415)، يعني جيڪڏهن توهان ڄاڻو ٿا ته ڪال قرار ڏنو ويو آهي

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

ته پوءِ توهان انتظار ڪري رهيا آهيو نه صرف هڪ ویکٹر جو، پر صارفين جي هڪ ویکٹر جو. وڌيڪ واضح طور تي، ٿيڻ گهرجي انتظار ڪريو - حقيقي ڪوڊ ۾، هر عنصر، جيڪڏهن بيئر قسم نه هجي، هڪ تعمير ڪندڙ هوندو، ۽ عمل ۾ سٺي طريقي سان اهو چيڪ ڪرڻ ضروري هوندو - ۽ اسان کي هن ویکٹر جي هر عنصر ۾ بلڪل موڪليو ويو آهي. اهو قسم؟ ۽ جيڪڏهن اهو ڪجهه قسم جو PHP هو، جنهن ۾ صف مختلف عناصر ۾ مختلف قسمن تي مشتمل ٿي سگهي ٿي؟

هن موقعي تي، توهان حيران ٿيڻ شروع ڪيو - ڇا اهڙي TL جي ضرورت آهي؟ ٿي سگهي ٿو ته ڪارٽ لاءِ انساني سيريلائزر استعمال ڪرڻ ممڪن هجي، ساڳيو پروٽوبف جيڪو اڳ ۾ ئي موجود هو؟ اهو نظريو هو، اچو ته عملي طور تي ڏسو.

ڪوڊ ۾ موجود TL لاڳو ڪرڻ

TL VKontakte جي آنڊن ۾ پيدا ٿيو هو جيتوڻيڪ مشهور واقعن کان اڳ Durov جي حصيداري جي وڪرو ۽ (بيشڪ)، جيتوڻيڪ ٽيليگرام جي ترقي کان اڳ. ۽ کليل ذريعو ۾ پهرين عملدرآمد جا ذريعا توھان تمام گھڻا مضحکہ خیز ڪچرا ڳولي سگھو ٿا. ۽ ٻولي پاڻ اتي لاڳو ڪئي وئي هئي ان کان وڌيڪ مڪمل طور تي اها هاڻي ٽيليگرام ۾ آهي. مثال طور، هيش اسڪيم ۾ بلڪل استعمال نه ڪيا ويا آهن (مطلب ته ٺهيل pseudotype (جهڙوڪ هڪ ویکٹر) deviant رويي سان). يا

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 - Type couples. C++ ۾ اهو ڪجهه هن طرح نظر ايندو:

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

تنهن ڪري، alpha - لفظ! پر صرف C++ ۾ توهان T لکي سگهو ٿا، پر توهان کي الفا، بيٽا لکڻو پوندو... پر 8 پيرا ميٽرن کان وڌيڪ نه، تصور ٿيٽا تي ختم ٿي ويو. تنهن ڪري اهو لڳي ٿو ته هڪ ڀيرو سينٽ پيٽرسبرگ ۾ تقريبن اهڙيون ڳالهيون هيون:

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

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

پر اهو TL جي "عام طور تي" جي پهرين ترتيب ڏنل نفاذ بابت هو. اچو ته اصل ٽيليگرام ڪلائنٽ ۾ عمل درآمد تي غور ڪريون.

باسل جو لفظ:

Vasily, [09.10.18/17/07 XNUMX:XNUMX] سڀ کان وڌيڪ، گدا ان حقيقت کان گرم آهي ته انهن خلاصن جي هڪ ٽولي کي ڇڪايو، ۽ پوء انهن تي هڪ بولٽ کي هٽائي ڇڏيو، ۽ ڪوڊيجگر تي ڪچرا وجهي.
نتيجي طور، پهرين ڊاک مان pilot.jpg
پوءِ jekichan.webp ڪوڊ مان

يقينن، ماڻهن کان جيڪي الگورتھم ۽ رياضيات سان واقف آهن، اسان اميد ڪري سگهون ٿا ته انهن Aho، Ullman کي پڙهيو آهي، ۽ انهن اوزارن کان واقف آهن جيڪي ڏهاڪن کان صنعت ۾ حقيقي معيار بڻجي چڪا آهن انهن جي ڊي ايس ايل لاء ڪمپلرز لکڻ لاء، صحيح؟ ..

ليکڪ telegram-cli آهي Vitaliy Valtman، جيئن سمجھي سگھجي ٿو TLO فارميٽ جي ان جي (cli) حدن کان ٻاهر، ٽيم جو ميمبر - ھاڻي TL کي پارس ڪرڻ لاءِ لائبريري مختص ڪئي وئي آھي الڳ الڳهن جو تاثر ڇا آهي TL parser؟ ..

16.12 04:18 واسيلي: منهنجي خيال ۾، ڪنهن lex + yacc ۾ مهارت حاصل نه ڪئي آهي
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);

Python ۾ 1100+ لائينون، ٻه ريگيولر ايڪسپريشنز + خاص ڪيس ویکٹر قسم جا، جن کي، يقينا، اسڪيم ۾ قرار ڏنو ويو آهي جيئن ته اهو TL نحو مطابق هجڻ گهرجي، پر اهي ان کي هن نحو تي رکي، ان کي وڌيڪ پارس ڪريو. ... سوال اهو آهي ته، هن سڄي معجزي سان ڇو تنگ ڪيو وڃي؟иوڌيڪ پف، جيڪڏهن ڪو به ان کي دستاويزن جي مطابق پارس ڪرڻ وارو ناهي؟!

رستي ۾... ياد رکو اسان CRC32 چيڪ بابت ڳالهايو هو؟ تنهن ڪري، ٽيليگرام ڊيسڪ ٽاپ ڪوڊ جنريٽر ۾ انهن قسمن جي استثناء جي هڪ فهرست آهي جنهن ۾ CRC32 جي حساب سان. نٿو ملي جيئن تصوير ۾ ڏيکاريل آهي!

واسيلي، [18.12 22:49] ۽ هتي توهان کي سوچڻ گهرجي ته ڇا اهڙي TL جي ضرورت آهي
جيڪڏهن مان متبادل لاڳو ڪرڻ سان گڙٻڙ ڪرڻ چاهيان ٿو، ته آئون لائين بريڪز داخل ڪرڻ شروع ڪندس، اڌ پارسر ملٽي لائين وصفن تي ڀڃندا
tdesktop، جيتوڻيڪ، پڻ

ون لائنرز جي باري ۾ نقطي کي ياد رکو، اسان ان کي ٿوري دير کان پوء واپس ڪنداسين.

ٺيڪ آهي، ٽيليگرام-ڪلي غير رسمي آهي، ٽيليگرام ڊيسڪ ٽاپ سرڪاري آهي، پر ٻين بابت ڇا؟ ۽ ڪير ڄاڻي ٿو؟.. Android ڪلائنٽ ڪوڊ ۾، ڪو به اسڪيما پارسر نه هو (جيڪو اوپن سورس بابت سوال اٿاري ٿو، پر اهو ٻئي حصي لاءِ آهي)، پر ڪوڊ جا ٻيا به ڪيترائي مضحکہ خیز ٽڪرا هئا، پر انهن بابت هيٺ ڏنل حصو.

سيريلائيزيشن عملي طور تي ٻيا ڪهڙا سوال اٿارين ٿا؟ مثال طور، اهي خراب ٿي ويا، يقينا، بٽ فيلڊ ۽ مشروط شعبن سان:

vasily: flags.0? true
مطلب ته فيلڊ موجود آهي ۽ صحيح آهي جيڪڏهن پرچم مقرر ڪيو ويو آهي

vasily: 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 parser شايد ان کي به نه کائيندو

// 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 ) ۽ هيٺين شرطن کي پورا ڪرڻ گهرجي:

  • part_size % 1024 = 0 (ورهائي سگهجي ٿو 1KB)
  • 524288 % part_size = 0 (512KB لازمي طور تي ورهائي سگهجي ٿو part_size)

آخري حصو انهن شرطن کي پورو ڪرڻ جي ضرورت ناهي، بشرطيڪ ان جي ماپ part_size کان گهٽ هجي.

هر حصو کي هڪ ترتيب نمبر هجڻ گهرجي، file_part0 کان 2,999 تائين جي قيمت سان.

فائل کي ورهاڱي کان پوء توهان کي سرور تي محفوظ ڪرڻ لاء هڪ طريقو چونڊڻ جي ضرورت آهي. استعمال ڪرڻ upload.saveBigFilePart صورت ۾ فائل جي مڪمل سائيز 10 MB کان وڌيڪ آهي ۽ upload.saveFilePart ننڍن فائلن لاء.
[...] ھيٺ ڏنل ڊيٽا ان پٽ غلطين مان ھڪڙي واپس ٿي سگھي ٿي:

  • FILE_PARTS_INVALID - حصن جو غلط تعداد. قدر جي وچ ۾ نه آهي 1..3000

ڇا انهن مان ڪو به اسڪيما ۾ موجود آهي؟ ڇا اهو ڪنهن به طرح TL جي ذريعي بيان ڪري سگهجي ٿو؟ نه. پر معاف ڪجو، ايستائين جو پراڻي دور جو ٽربو پاسڪل به انهن قسمن کي بيان ڪرڻ جي قابل هو. حدون. ۽ هو هڪ ٻيو ڪم ڪري سگهي ٿو، هاڻي بهتر طور سڃاتو وڃي ٿو enum - ھڪڙو قسم آھي جنھن ۾ ھڪڙي مقرر ڪيل (ننڍي) قدرن جي ڳڻپ شامل آھي. ٻولين ۾ جهڙوڪ C - عددي، ياد رکو، اسان هن وقت تائين صرف قسمن بابت ڳالهايو آهي. انگ. پر هتي پڻ آهن arrays، strings... مثال طور، اهو بيان ڪرڻ سٺو لڳندو ته هي اسٽرنگ صرف فون نمبر تي مشتمل ٿي سگهي ٿو، صحيح؟

TL ۾ هن مان ڪوبه ناهي. پر اتي آھي، مثال طور، JSON اسڪيما ۾. ۽ جيڪڏهن ڪو ٻيو اعتراض ڪري سگهي ٿو 512 KB جي تقسيم جي باري ۾ ته اهو اڃا تائين ڪوڊ ۾ چيڪ ڪرڻ جي ضرورت آهي، پوء پڪ ڪريو ته ڪلائنٽ صرف مان نه ڪري سگھيس حد کان ٻاهر نمبر موڪليو 1..3000 (۽ لاڳاپيل غلطي پيدا نه ٿي سگهي ها) اهو ممڪن آهي، صحيح؟ ..

رستي جي ذريعي، غلطين ۽ واپسي جي قيمتن بابت. اکيون انهن لاءِ به blurred آهن جن TL سان ڪم ڪيو آهي - اهو اسان تي فوري طور تي صبح نه ٿيو هر هڪ TL ۾ هڪ فنڪشن اصل ۾ نه رڳو بيان ڪيل واپسي جي قسم کي واپس ڪري سگهي ٿو، پر هڪ غلطي پڻ. پر اهو خود TL جي ذريعي قابل نه آهي. يقينن، اهو بهرحال سمجهي سگهجي ٿو ۽ عملي طور تي نافيگ ضروري ناهي (جيتوڻيڪ حقيقت ۾، آر پي سي مختلف طريقن سان ٿي سگهي ٿو، اسان هن ڏانهن موٽنداسين) - پر ڇا آسماني کان خلاصي قسم جي رياضي جي تصورات جي خالصيت بابت؟ دنيا?

۽ آخرڪار، پڙهڻ جي صلاحيت بابت ڇا؟ خير، اتي، عام طور تي، مان چاهيان ٿو بيان ڇا اهو صحيح اسڪيما ۾ آهي (ٻيهر، اهو 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 تہن کان پوء، ھڪڙي آفاقي ٺاھيندڙ ھڪڙي ورزن نمبر سان آخرڪار شامل ڪيو ويو، جنھن کي ڪنيڪشن جي شروعات ۾ صرف ھڪڙو ڀيرو سڏڻ جي ضرورت آھي، ۽ تہن ۾ معني غائب ٿيڻ لڳي، ھاڻي اھو صرف ھڪڙو مشروط نسخو آھي، جھڙوڪ هر هنڌ ٻيو. مسئلو حل ٿي ويو.

ساڄو؟..

Vasily, [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 (جيڪو ورزن ڪيترن ئي لينڪس ڊسٽريبيوشن سان فراهم ڪيو ويو آهي)، اهو لکي ٿو Exception log: MTP Unexpected type id #b5223b0f MTPMessageMedia ۾ پڙهو…

ٽيليگرام جي پروٽوڪول ۽ تنظيمي طريقن جي تنقيد. حصو 1، ٽيڪنيڪل: شروع کان ڪلائنٽ لکڻ جو تجربو - TL، MT

گوگل ڏيکاريو ته ساڳيو مسئلو اڳ ۾ ئي هڪ غير رسمي ڪلائنٽ سان ٿي چڪو آهي، پر پوء نسخي نمبر ۽، مطابق، مفروضا مختلف هئا ...

پوءِ ڇا ڪجي؟ واسيلي ۽ مان جدا ٿي ويا: هن اسڪيم کي 91 تائين اپڊيٽ ڪرڻ جي ڪوشش ڪئي، مون ڪجهه ڏينهن انتظار ڪرڻ جو فيصلو ڪيو ۽ 73 تائين ڪوشش ڪرڻ جو فيصلو ڪيو. ٻنهي طريقن ڪم ڪيو، پر جيئن ته اهي تجرباتي آهن، توهان کي خبر ناهي ته توهان کي ڪيترا نسخو جمپ اپ ڪرڻ جي ضرورت آهي. يا هيٺ، ۽ نه ئي توهان کي ڪيترو وقت انتظار ڪرڻو پوندو.

بعد ۾، مون صورتحال کي ٻيهر پيدا ڪرڻ جو انتظام ڪيو: اسان ڪلائنٽ کي شروع ڪريون ٿا، ان کي بند ڪريون، اسڪيم کي ٻي پرت ۾ ٻيهر ترتيب ڏيو، ٻيهر شروع ڪريو، ٻيهر مسئلو کي پڪڙيو، پوئين ڏانهن واپس وڃو - اوهه، اسڪيم کي تبديل نه ڪيو ۽ ڪيترن ئي لاء ڪلائنٽ کي ٻيهر شروع ڪيو. منٽ مدد ڪندو. توهان مختلف پرتن مان ڊيٽا جي جوڙجڪ جو هڪ ميلاپ وصول ڪندا.

وضاحت؟ جئين توهان مختلف اڻ سڌي طرح علامات مان اندازو لڳائي سگهو ٿا، سرور مختلف مشينن تي ڪيترن ئي مختلف قسمن جي عملن تي مشتمل آهي. گهڻو ڪري، سرورن مان هڪ جيڪو "بفرنگ" لاء ذميوار آهي قطار ۾ رکي ٿو جيڪو اعلي ماڻهن ڏنو آهي، ۽ انهن ان کي ڏنو اسڪيم ۾ جيڪو نسل جي وقت ۾ هو. ۽ جيستائين هي قطار ”سڙيل“ نه هئي، ان بابت ڪجهه به نه ٿي سگهيو.

جيستائين... پر هي هڪ خوفناڪ ڪچرو آهي؟!.. نه، پاگل خيالن جي باري ۾ سوچڻ کان اڳ، اچو ته سرڪاري گراهڪن جو ڪوڊ ڏسو. Android ورزن ۾، اسان کي ڪو به TL پارسر نه ملندو، پر اسان کي (ڊي) سيريلائيزيشن سان گڏ هڪ وڏي فائل (گيٿب ان کي رنگ ڏيڻ کان انڪار ڪري ٿو) ڳوليندا آهيون. هتي ڪوڊ جا ٽڪرا آهن:

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 جي تحت هڪ لا بلب)، پر اهو اڳ ۾ ئي ٻئي حصي لاء هڪ موضوع آهي.

پر ڪافي. اچو ته ان پروٽوڪول ڏانهن وڃو جنهن جي مٿان اهو سڀ سيريلائيزيشن کي ڇڪي رهيو آهي.

ايم پي پروٽو

سو اچو ته کوليون عام وضاحت и پروٽوڪول جي تفصيلي وضاحت ۽ پھرين شيءِ جنھن تي اسين ٿڪجي پيا آھيون اھو آھي اصطلاح. ۽ هر شيء جي گهڻائي سان. عام طور تي، هي ٽيليگرام جو هڪ ٽريڊ مارڪ لڳي ٿو - مختلف هنڌن تي مختلف طريقن سان، يا مختلف شين کي هڪ لفظ ۾، يا ان جي برعڪس (مثال طور، هڪ اعلي سطحي API ۾ جيڪڏهن توهان هڪ اسٽيڪر پيڪ ڏسو - هي اهو نه آهي جيڪو توهان سوچيو).

مثال طور، "پيغام" (پيغام) ۽ "سيشن" (سيشن) - هتي انهن جو مطلب آهي ٽيليگرام ڪلائنٽ جي معمولي انٽرفيس کان مختلف. خير، پيغام سان سڀ ڪجهه واضح آهي، اهو OOP جي لحاظ سان تشريح ڪري سگهجي ٿو، يا صرف لفظ "پيڪيج" سڏيو ويندو آهي - اهو هڪ گهٽ، ٽرانسپورٽ جي سطح آهي، اتي ساڳيو پيغام نه آهن جيئن انٽرفيس ۾، اتي تمام گهڻو آهن. خدمتن جي. پر سيشن ... پر پهرين شيون پهرين.

ٽرانسپورٽ پرت

پهرين شيء ٽرانسپورٽ آهي. اسان کي 5 اختيارن بابت ٻڌايو ويندو:

  • ٽي پي
  • ويب ساکٽ
  • HTTPS تي ويب ساکٽ
  • HTTP
  • اي ٽي پي پي

واسيلي، [15.06.18/15/04 XNUMX:XNUMX PM] ۽ اتي پڻ UDP ٽرانسپورٽ آهي، پر اهو دستاويز نه آهي

۽ ٽي سي پي ٽن قسمن ۾

پهرين TCP مٿان UDP سان ملندڙ جلندڙ آهي، هر پيڪٽ ۾ هڪ ترتيب نمبر ۽ هڪ سي آر سي شامل آهي
ڪارٽ تي ڊاک پڙهڻ ايترو ڏکوئيندڙ ڇو آهي؟

خير اتي هاڻي TCP اڳ ۾ ئي 4 مختلف قسمن ۾:

  • وڌايو ويو
  • بيوت
  • وچولي padded
  • سڄو

ٺيڪ، MTProxy لاءِ پيڊل وچولي، اهو بعد ۾ ڄاڻايل واقعن جي ڪري شامل ڪيو ويو. پر ڇو ٻه وڌيڪ نسخو (مجموعي طور تي ٽي)، جڏهن هڪ ڪري سگهي ٿو؟ سڀئي چار بنيادي طور تي صرف ان ۾ فرق ڪن ٿا ته مکيه MTProto جي ڊيگهه ۽ پيل لوڊ ڪيئن ڪجي، جنهن تي وڌيڪ بحث ڪيو ويندو:

  • مختصر ۾ اهو 1 يا 4 بائيٽ آهي پر نه 0xef پوءِ جسم
  • انٽرميڊيٽ ۾ هي 4 بائيٽ جي ڊيگهه ۽ هڪ فيلڊ آهي، ۽ پهريون ڀيرو ڪلائنٽ موڪلڻ گهرجي 0xeeeeeeee ظاهر ڪرڻ لاءِ ته اهو وچولي آهي
  • مڪمل ۾، سڀ کان وڌيڪ لت، نيٽ ورڪر جي نقطي نظر کان: ڊگھائي، ترتيب نمبر، ۽ ھڪڙو نه آھي جيڪو بنيادي طور تي MTProto، جسم، CRC32 آھي. ها، هي سڀ TCP تي. جيڪو اسان کي قابل اعتماد ٽرانسپورٽ فراهم ڪري ٿو بائيٽ جي سيريل وهڪرو جي صورت ۾، ڪنهن به ترتيب جي ضرورت ناهي، خاص طور تي چيڪسم. ٺيڪ، هاڻي مون کي اعتراض ٿيندو ته TCP وٽ 16-bit چيڪسم آهي، ان ڪري ڊيٽا ڪرپشن ٿئي ٿي. عظيم، سواءِ ان جي ته اسان وٽ اصل ۾ هڪ cryptographic protocol آهي hashes سان 16 bytes کان وڌيڪ ڊگهو، اهي سڀئي غلطيون - ۽ اڃا به وڌيڪ - هڪ اعلي سطح تي SHA بي ميل تي پڪڙي ويندي. هن تي CRC32 ۾ ڪو به نقطو ناهي.

اچو ته Abridged جو موازنہ ڪريون، جتي هڪ بائيٽ جي ڊيگهه ممڪن آهي، انٽرميڊيٽ سان، جيڪو جواز ڏئي ٿو "جيڪڏهن 4-بائيٽ ڊيٽا جي ترتيب جي ضرورت آهي"، جيڪا ڪافي بيوقوف آهي. ڇا، اهو يقين آهي ته ٽيليگرام پروگرامر ايترا بيڪار آهن ته اهي ساکٽ مان ڊيٽا کي ترتيب ڏنل بفر ۾ پڙهي نٿا سگهن؟ توھان کي اڃا تائين اھو ڪرڻو پوندو، ڇو ته پڙھڻ توھان کي بائيٽ جو تعداد واپس ڪري سگھي ٿو (۽ پراکسي سرور پڻ آھن، مثال طور ...). يا، ٻئي طرف، ڇو تنگ ڪرڻ سان تنگ ڪيو وڃي جيڪڏهن اسان وٽ اڃا تائين 16 بائيٽس کان مٿانهون آهن - 3 بائيٽ بچايو ڪڏهن ڪڏهن ?

هڪ اهو تاثر حاصل ڪري ٿو ته نيڪولائي دوروف سائيڪلن کي ايجاد ڪرڻ جو ڏاڍو شوق آهي، بشمول نيٽ ورڪ پروٽوڪول، حقيقي عملي ضرورت کان سواء.

ٻيا ٽرانسپورٽ جا اختيار، بشمول. ويب ۽ MTProxy، اسان هاڻي غور نه ڪنداسين، شايد ٻي پوسٽ ۾، جيڪڏهن ڪا درخواست آهي. اسان صرف هن MTProxy جي باري ۾ صرف ياد ڪنداسين ته جلد ئي 2018 ۾ ان جي رليز ٿيڻ کان پوء، مهيا ڪندڙن کي جلدي جلدي ان کي بلاڪ ڪرڻ سکيو، مقصد لاء. بلاڪ بائي پاسطرفان پيڪيج جي ماپ! ۽ اها به حقيقت آهي ته MTProxy سرور لکيو ويو (ٻيهر والٽمن طرفان) سي ۾ غير ضروري طور تي لينڪس جي وضاحتن سان ڳنڍيل هو، جيتوڻيڪ اهو بلڪل گهربل نه هو (فل ڪولين تصديق ڪندو)، ۽ اهو ساڳيو سرور يا ته Go يا Node.js تي. سؤ لائينن کان به گھٽ.

پر انهن ماڻهن جي فني خواندگيءَ جي باري ۾ اسان سيڪشن جي آخر ۾ ٻين مسئلن تي غور ڪرڻ کان پوءِ نتيجو ڪڍنداسين. ھاڻي، اچو ته 5th OSI پرت ڏانھن وڃو، سيشن - جنھن تي ھنن ايم ٽي پروٽو سيشن رکيو.

چاٻيون، نياپا، سيشن، ڊيفي-هيلمن

اھي اُھي اُتي رکيا آھن بلڪل صحيح طرح... سيشن اھو سيشن ناھي جيڪو فعال سيشن جي ھيٺان انٽرفيس ۾ نظر اچي. پر ترتيب ۾.

ٽيليگرام جي پروٽوڪول ۽ تنظيمي طريقن جي تنقيد. حصو 1، ٽيڪنيڪل: شروع کان ڪلائنٽ لکڻ جو تجربو - TL، MT

هتي اسان کي ٽرانسپورٽ جي پرت مان معلوم لمبائي جي بائيٽ جي هڪ تار ملي آهي. اهو يا ته هڪ اينڪرپٽ ٿيل پيغام يا سادي متن آهي - جيڪڏهن اسان اڃا تائين اهم ڳالهين واري مرحلي تي آهيون ۽ حقيقت ۾ اهو ڪري رهيا آهيون. تصورن جي ڪھڙي ٽولي جي باري ۾ اسين ڳالھائي رھيا آھيون ”ڪي“؟ اچو ته هن مسئلي کي پاڻ ٽيليگرام ٽيم لاءِ واضح ڪريون (مان پنهنجي دستاويز کي انگريزيءَ مان ترجمو ڪرڻ تي معذرت ڪريان ٿو يا ته صبح جو 4 وڳي ٿڪل دماغ ۾، ڪجهه جملا جيئن ته اهي آهن ڇڏڻ آسان هو):

اتي ٻه ادارا سڏجن ٿا اجلاس - سرڪاري ڪلائنٽ جي UI ۾ "موجوده سيشن" جي تحت، جتي هر سيشن پوري ڊوائيس / او ايس سان ملندو آهي.
ٻيون - MTProto سيشن، جنهن ۾ هڪ پيغام جي ترتيب نمبر آهي (گهٽ سطحي معنيٰ ۾) ان ۾، ۽ جيڪو مختلف TCP ڪنيڪشن جي وچ ۾ آخري ٿي سگھي ٿو. ڪيترائي MTProto سيشن ساڳئي وقت سيٽ ڪري سگھجن ٿا، مثال طور، فائل ڊائون لوڊ کي تيز ڪرڻ لاءِ.

انهن ٻنهي جي وچ ۾ سيشن تصور آهي اختيار ڏيڻ. تنزل جي صورت ۾، ڪو به چئي سگهي ٿو UI سيشن ساڳيو آهي اختيار ڏيڻپر افسوس، اهو پيچيده آهي. اسين ڏسون ٿا:

  • نئين ڊوائيس تي صارف پهريون ڀيرو ٺاهي ٿو auth_key ۽ ان کي اڪائونٽ تائين محدود ڪري ٿو، مثال طور، ايس ايم ايس ذريعي - اهو ئي سبب آهي اختيار ڏيڻ
  • اهو پهريون اندر ٿيو MTProto سيشن، جنهن وٽ آهي session_id پنهنجي اندر.
  • هن قدم تي، ميلاپ اختيار ڏيڻ и session_id سڏي سگهجي ٿو دليل - هي لفظ ڪجهه گراهڪن جي دستاويزن ۽ ڪوڊ ۾ ملي ٿو
  • پوء، ڪلائنٽ کوليو ويندو ڪيترن MTProto سيشن ساڳئي تحت auth_key - ساڳئي ڊي سي ڏانهن.
  • پوءِ هڪ ڏينهن ڪلائنٽ کان فائل جي درخواست ڪرڻ جي ضرورت آهي ٻيو ڊي سي - ۽ ان لاءِ ڊي سي نئون ٺاھيو ويندو auth_key !
  • سسٽم کي ٻڌائڻ لاءِ ته هي نئون يوزر رجسٽريشن نه آهي، پر ساڳيو آهي اختيار ڏيڻ (UI سيشن)، ڪلائنٽ API ڪالون استعمال ڪري ٿو auth.exportAuthorization گهر ۾ ڊي سي auth.importAuthorization نئين ڊي سي ۾.
  • سڀ ساڳيو، اتي ڪيترن ئي کليل ٿي سگهي ٿو MTProto سيشن (هر هڪ پنهنجي پنهنجي session_id) هن نئين ڊي سي ڏانهن، هيٺ سندس auth_key.
  • آخرڪار، گراهڪ شايد مڪمل فارورڊ رازداري چاهي ٿو. هر auth_key هو مستقل key - per DC - ۽ ڪلائنٽ ڪال ڪري سگهي ٿو auth.bindTempAuthKey استعمال لاءِ عارضي طور تي auth_key - ۽ ٻيهر، صرف هڪ temp_auth_key في ڊي سي، سڀني لاءِ عام MTProto سيشن هن ڊي سي ڏانهن.

نوٽيس، اهو لوڻ (۽ مستقبل جي لوڻ) پڻ هڪ تي auth_key اهي. سڀني جي وچ ۾ حصيداري MTProto سيشن ساڳئي ڊي سي ڏانهن.

"مختلف TCP ڪنيڪشن جي وچ ۾" ڇا مطلب آهي؟ مطلب ته هي ڪجهه جهڙو ويب سائيٽ تي اختيار ڏيڻ واري ڪوڪي - اها برقرار رهي ٿي (بچي ٿي) ڪيترن ئي TCP ڪنيڪشن هن سرور سان، پر هڪ ڏينهن اهو خراب ٿي ويندو. صرف HTTP جي برعڪس، MTProto ۾، سيشن جي اندر، پيغامن کي ترتيب سان نمبر ۽ تصديق ٿيل آهن، اهي سرنگ ۾ داخل ٿيا، ڪنيڪشن ٽوڙيو ويو - هڪ نئون ڪنيڪشن قائم ڪرڻ کان پوء، سرور مهرباني ڪري هن سيشن ۾ سڀ ڪجهه موڪليندو جيڪو هن سيشن ۾ نه پهچايو هو. اڳوڻو TCP ڪنيڪشن.

بهرحال، مٿي ڄاڻايل معلومات ڪيترن ئي مهينن جي مقدمي کان پوء هڪ نچوض آهي. ساڳئي وقت ۾، ڇا اسان پنهنجي ڪلائنٽ کي شروع کان لاڳو ڪري رهيا آهيون؟ - اچو ته شروعات ڏانھن واپس وڃو.

تنهنڪري اسان پيدا ڪريون ٿا auth_key تي ٽيليگرام کان Diffie-Hellman جو نسخو. اچو ته دستاويز کي سمجهڻ جي ڪوشش ڪريون...

واسيلي، [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. پر جڏهن ته هي بظاهر سادو آپريشن ڪامياب ٿئي ٿو، توهان کي ڇا منهن ڏيڻو پوندو؟

Vasily, [20.06.18/00/26 XNUMX:XNUMX] مان اڃا تائين اپيل جي درخواست تي نه پهتو آهيان

مون ڊي ايڇ او کي درخواست موڪلي

۽، ٽرانسپورٽ تي ڊاک ۾ اهو لکيل آهي ته اهو غلطي ڪوڊ جي 4 بائيٽ سان جواب ڏئي سگهي ٿو. ۽ اهو آهي

خير، هن مون کي ٻڌايو -404، پوء ڇا؟

هتي مان هن ڏانهن آهيان: "پڪڙ پنهنجي efigna کي اينڪرپٽ ٿيل سرور ڪيئي سان هڪ فنگر پرنٽ سان اهڙي ۽ اهڙي، مون کي 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] تقريبن

مون کي سادو تقسيم ڪندڙ٪) ۾ اهڙي خرابي نه ملي.

جيتوڻيڪ غلطي جي رپورٽنگ کي ماهر نه ڪيو ويو

واسيلي، [20.06.18/20/18 5:XNUMX PM] اوه، اتي پڻ MDXNUMX آهي. اڳ ۾ ئي ٽي مختلف hashes

ڪنجي فنگر پرنٽ جي حساب سان ھيٺ ڏنل آھي:

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

SHA1 ۽ sha2

سو اچو ته وجھون auth_key 2048 بٽ سائيز ۾ اسان ڊفي-هيلمن جي مطابق حاصل ڪيو. اڳتي ڇا آهي؟ پوءِ اسان کي معلوم ٿيو ته هن ڪيئي جا هيٺيون 1024 بِٽ ڪنهن به طرح استعمال نه ڪيا ويا آهن ... پر اچو ته هن وقت لاءِ سوچيون. هن قدم تي، اسان وٽ سرور سان هڪ گڏيل راز آهي. TLS سيشن جو هڪ اينالاگ قائم ڪيو ويو آهي، هڪ تمام قيمتي طريقيڪار. پر سرور کي ڪا به خبر ناهي ته اسان ڪير آهيون! اڃا نه، اصل ۾ اجازت ڏيڻ. اهي. جيڪڏهن توهان سوچيو ته "لاگ ان-پاسورڊ" جي اصطلاحن ۾، جيئن اهو ICQ ۾ هوندو هو، يا گهٽ ۾ گهٽ "لاگ ان-ڪي"، جيئن SSH ۾ (مثال طور، ڪجهه گٽلب / گيٽب تي). اسان گمنام ٿي ويا. ۽ جيڪڏهن سرور اسان کي جواب ڏئي ٿو "اهي فون نمبر ڪنهن ٻئي ڊي سي طرفان خدمت ڪيا ويا آهن"؟ يا اڃا به "توهان جو فون نمبر منع ٿيل آهي"؟ بهترين شيء جيڪا اسان ڪري سگهون ٿا اهو آهي ته اميد ۾ ڪنجي کي محفوظ ڪيو وڃي ته اهو اڃا تائين ڪارائتو ٿيندو ۽ ان وقت تائين خراب نه ٿيندو.

رستي جي ذريعي، اسان ان کي تحفظات سان "حاصل" ڪيو. مثال طور، ڇا اسان سرور تي ڀروسو ڪندا آهيون؟ ڇا هو جعلي آهي؟ اسان کي cryptographic چيڪن جي ضرورت آهي:

Vasily, [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)) {

نه، يقيناً اتي ڪجهه انگن جي سادگي لاءِ چيڪ آهن، پر ذاتي طور تي مون کي هاڻي رياضي ۾ ڪافي ڄاڻ ناهي.

چڱو، اسان کي ماسٽر چاٻي ملي. لاگ ان ٿيڻ لاءِ، يعني درخواستون موڪليو، ان کي وڌيڪ انڪرپشن انجام ڏيڻ ضروري آهي، اڳ ۾ ئي AES استعمال ڪندي.

ميسيج ڪيئي جي وضاحت ڪئي وئي آهي SHA128 جي ميسيج باڊي جي 256 وچين بِٽس (بشمول سيشن، ميسيج آئي ڊي، وغيره)، جنهن ۾ پيڊنگ بائٽس شامل آهن، 32 بائٽس جي اڳڀرائي ڪئي وئي آهي، جيڪا اختيار ڪرڻ واري ڪي مان ورتي وئي آهي.

Vasily, [22.06.18/14/08 XNUMX:XNUMX PM] سراسري ڪچي

مليل auth_key. سڀ. انهن کي وڌيڪ ... اهو ڊاکن مان صاف ناهي. اوپن سورس ڪوڊ پڙهڻ لاءِ آزاد ٿيو.

نوٽ ڪريو ته MTProto 2.0 جي ضرورت آهي 12 کان 1024 بائيٽ جي پيڊنگ، اڃا به ان شرط سان مشروط آهي ته نتيجي ۾ آيل پيغام جي ڊيگهه 16 بائيٽ سان ورهائجي.

پوءِ ڪيتري پيڊنگ ۾ رکڻ لاءِ؟

۽ ها، هتي، پڻ، 404 غلطي جي صورت ۾

جيڪڏهن ڪو ماڻهو احتياط سان ڊاگرام ۽ دستاويز جي متن جو مطالعو ڪيو، هن محسوس ڪيو ته اتي ڪوبه MAC موجود ناهي. ۽ اهو AES استعمال ڪيو ويو آهي ڪجهه IGE موڊ ۾ جيڪو ڪٿي به استعمال نه ڪيو ويو آهي. اهي، يقيناً، ان جي باري ۾ انهن جي اڪثر سوالن ۾ لکندا آهن... هتي، جهڙوڪ، پيغام جي ڪيئي پاڻ هڪ ئي وقت ڊيڪرپٽ ٿيل ڊيٽا جو SHA هيش آهي جيڪو سالميت کي جانچڻ لاءِ استعمال ڪيو ويو آهي - ۽ بي ميل ٿيڻ جي صورت ۾، دستاويز ڪجهه سببن جي سفارش ڪري ٿو خاموشيء سان انهن کي نظر انداز ڪرڻ (پر ڇا سيڪيورٽي بابت، اوچتو اسان کي ٽوڙيو؟).

مان هڪ cryptographer نه آهيان، شايد هن موڊ ۾ هن صورت ۾ نظرياتي نقطي نظر کان ڪجھ به غلط ناهي. پر مان ضرور هڪ عملي مسئلي جو نالو ڏئي سگهان ٿو، مثال استعمال ڪندي ٽيليگرام ڊيسڪ ٽاپ. اهو مقامي ڪيش (اهي سڀ D877F783D5D3EF8C) کي انڪريپ ڪري ٿو جيئن MTProto ۾ پيغامن (صرف هن صورت ۾، نسخو 1.0)، يعني. پهرين پيغام جي ڪنجي، پوءِ ڊيٽا پاڻ (۽ ٻي جاءِ تي مکيه وڏو auth_key 256 بائيٽ، جنهن کان سواءِ msg_key بيڪار). تنهن ڪري، مسئلو وڏي فائلن تي قابل ذڪر ٿيندو. يعني، توهان کي ڊيٽا جون ٻه ڪاپيون رکڻ جي ضرورت آهي - انڪوڊ ٿيل ۽ ڊريڪٽ ٿيل. ۽ جيڪڏھن اتي ميگا بائيٽ آھن، يا وڊيو اسٽريمنگ، مثال طور؟ .. ڪلاسڪ اسڪيمون ميڪ سان گڏ سيفر ٽيڪسٽ کان پوءِ توھان کي پڙھڻ جي اجازت ڏين ٿيون ان کي اسٽريمنگ پڙھڻ، فوري طور تي منتقل ڪرڻ. ۽ MTProto سان توهان کي ڪرڻو پوندو پهرين تي پوري پيغام کي انڪريپٽ يا ڊڪرپٽ ڪريو، صرف پوءِ ان کي نيٽ ورڪ يا ڊسڪ ڏانھن منتقل ڪريو. تنهن ڪري، ڪيش ۾ ٽيليگرام ڊيسڪ ٽاپ جي جديد نسخن ۾ user_data ٻيو فارميٽ اڳ ۾ ئي استعمال ڪيو ويو آهي - CTR موڊ ۾ AES سان.

واسيلي، [21.06.18/01/27 20:XNUMX AM] اوه، مون کي معلوم ٿيو ته IGE ڇا آهي: IGE پهرين ڪوشش هئي "تصديق واري انڪرپشن موڊ" تي، اصل ۾ ڪربروس لاءِ. اها هڪ ناڪام ڪوشش هئي (اهو سالميت جي تحفظ فراهم نٿو ڪري)، ۽ هٽايو وڃي ها. اها شروعات هئي XNUMX سالن جي ڳولا جي هڪ تصديق ڪندڙ انڪرپشن موڊ لاءِ جيڪو ڪم ڪري ٿو، جيڪو تازو ئي OCB ۽ GCM وانگر طريقن ۾ ختم ٿيو.

۽ هاڻي ڪارٽ جي پاسي کان دليل:

ٽيليگرام جي پويان ٽيم، نيڪولائي دوروف جي اڳواڻي ۾، ​​ڇهه ACM چيمپين تي مشتمل آهي، جن مان اڌ رياضي ۾ پي ايڇ ڊي. MTProto جي موجوده ورزن کي رولٽ ڪرڻ ۾ کين اٽڪل ٻه سال لڳي ويا.

ڪهڙو مذاق آهي. ٻه سال هيٺين سطح تائين

يا اسان صرف tls وٺي سگهون ٿا

ٺيڪ آهي، اچو ته چئو ته اسان انڪريپشن ۽ ٻين nuances ڪيو آهي. ڇا اسان آخرڪار TL-سيريل ٿيل درخواستون موڪلي سگھون ٿا ۽ جوابن کي ختم ڪري سگھون ٿا؟ پوء ڇا موڪلڻ گهرجي ۽ ڪيئن؟ هتي جو طريقو آهي initConnectionشايد اهو ئي آهي؟

Vasily, [25.06.18/18/46 XNUMX:XNUMX PM] ڪنيڪشن کي شروع ڪري ٿو ۽ صارف جي ڊوائيس ۽ ايپليڪيشن تي معلومات محفوظ ڪري ٿو.

اهو قبول ڪري ٿو app_id، device_model، system_version، app_version ۽ lang_code.

۽ ڪجھ سوال

دستاويز هميشه وانگر. کليل ذريعو پڙهڻ لاء آزاد محسوس ڪريو

جيڪڏهن سڀ ڪجهه واضح طور تي invokeWithLayer سان صاف هو، پوء اهو ڇا آهي؟ اهو ظاهر ٿيو ته فرض ڪريو اسان وٽ آهي - ڪلائنٽ اڳ ۾ ئي سرور کان پڇڻ لاءِ ڪجهه آهي - اتي هڪ درخواست آهي جيڪا اسان موڪلڻ چاهيون ٿا:

واسيلي، [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، ۽ جنهن کان پوءِ اسان کي ڪوڊ سان هڪ ايس ايم ايس ملي ٿو. ۽ جيڪڏھن اسان غلط ڊي سي ڏانھن ويا آھيون (ھن ملڪ جا فون نمبر ٻئي طرفان ڏنا ويا آھن، مثال طور)، پوء اسان کي مطلوب ڊي سي جي نمبر سان غلطي ملندي. معلوم ڪرڻ لاءِ جنهن IP پتي کي اسان کي ڊي سي نمبر سان ڳنڍڻ جي ضرورت آهي، اسان جي مدد ڪئي ويندي 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 وغيره، هي نه آهي بس عام درخواست. الڳ الڳ، اهو پڻ فراهم ڪري ٿو ته توهان وٽ ڊي سي تي صرف هڪ عارضي چيڪ رکي سگهي ٿي، جيتوڻيڪ فيلڊ auth_key_id هر پيغام ۾ توهان کي اجازت ڏئي ٿو ته گهٽ ۾ گهٽ هر پيغام جي ڪيچي کي تبديل ڪرڻ، ۽ اهو سرور کي حق آهي ته ڪنهن به وقت عارضي ڪنجي کي "وساري" - هن صورت ۾ ڇا ڪجي، دستاويز نه چوندا آهن ... خير، ڇو اهو ممڪن ناهي ته ڪيترن ئي ڪنجيون هجن، جيئن مستقبل جي نموني جي هڪ سيٽ سان، پر؟

اتي ڪجھ ٻيون شيون آھن جيڪي قابل ذڪر آھن MTProto موضوع ۾.

نياپا نياپا، msg_id، msg_seqno، اعتراف، پنگس غلط طرف ۽ ٻيا محاورا

توهان کي انهن بابت ڄاڻڻ جي ضرورت ڇو آهي؟ ڇو ته اهي "ليڪ" هڪ سطح کان وڌيڪ آهن، ۽ توهان کي انهن بابت ڄاڻڻ جي ضرورت آهي جڏهن API سان ڪم ڪندي. فرض ڪريو اسان کي msg_key ۾ دلچسپي نه آهي، هيٺئين سطح اسان لاءِ هر شيءِ کي ڊڪرائي ڇڏيو. پر ڊيڪرپٽ ٿيل ڊيٽا جي اندر، اسان وٽ ھيٺيون فيلڊون آھن (پڻ ڊيٽا جي ڊگھائي ڄاڻڻ لاءِ ته پيڊنگ ڪٿي آھي، پر اھو ضروري نه آھي):

  • لوڻ-int64
  • session_id - int64
  • message_id - int64
  • seq_no-int32

ياد رهي ته سڄي ڊي سي لاءِ رڳو هڪ لوڻ آهي. هن جي باري ۾ ڇو ڄاڻو؟ نه رڳو ڇو ته اتي هڪ درخواست آهي get_future_salts، جيڪو ٻڌائي ٿو ته ڪهڙا وقفا صحيح هوندا، پر اهو پڻ ڇو ته جيڪڏهن توهان جو لوڻ ”سڙيل“ آهي، ته پوءِ پيغام (درخواست) بس گم ٿي ويندو. سرور ضرور جاري ڪندي نئين لوڻ جي رپورٽ ڪندو new_session_created - پر پراڻي سان توهان کي ڪنهن به طرح ٻيهر موڪلڻو پوندو، مثال طور. ۽ هي سوال ايپليڪيشن جي فن تعمير کي متاثر ڪري ٿو.

سرور کي اجازت آهي ته سيشن کي مڪمل طور تي ڇڏي ڏيو ۽ ڪيترن ئي سببن لاء هن طريقي سان جواب ڏيو. دراصل، ڪلائنٽ جي پاسي کان هڪ MTProto سيشن ڇا آهي؟ اهي ٻه نمبر آهن session_id и seq_no هن سيشن ۾ پيغام. خير، ۽ بنيادي TCP ڪنيڪشن، يقينا. اچو ته چئو ته اسان جي ڪلائنٽ اڃا تائين نه ڄاڻن ٿا ته ڪيتريون ئي شيون ڪيئن ڪجي، منقطع، ٻيهر ڳنڍجي. جيڪڏهن اهو جلدي ٿيو - پراڻي سيشن نئين ٽي سي پي ڪنيڪشن ۾ جاري رهي، وڌايو seq_no وڌيڪ. جيڪڏهن اهو گهڻو وقت وٺندو آهي، سرور ان کي ختم ڪري سگهي ٿو، ڇاڪاڻ ته ان جي پاسي تي اهو پڻ هڪ قطار آهي، جيئن اسان کي معلوم ٿيو.

ڇا ٿيڻ گهرجي seq_no؟ ها، اهو هڪ مشڪل سوال آهي. ايمانداري سان سمجھڻ جي ڪوشش ڪريو مطلب ڇا آھي:

مواد سان لاڳاپيل پيغام

ھڪڙو پيغام جيڪو واضح طور تي تسليم ڪرڻ جي ضرورت آھي. انهن ۾ شامل آهن سڀئي صارف ۽ ڪيترائي خدمت جا پيغام، تقريبن سڀئي ڪنٽينرز ۽ اعترافن جي استثنا سان.

پيغام جي ترتيب نمبر (msg_seqno)

هڪ 32-بٽ نمبر "مواد سان لاڳاپيل" پيغامن جي ٻه ڀيرا جي برابر آهي (جن کي تسليم ڪرڻ جي ضرورت آهي، ۽ خاص طور تي اهي جيڪي ڪنٽينر نه آهن) هن پيغام کان اڳ موڪليندڙ پاران ٺاهيل آهن ۽ بعد ۾ هڪ طرفان وڌايو ويو آهي جيڪڏهن موجوده پيغام هڪ آهي. مواد سان لاڳاپيل پيغام. هڪ ڪنٽينر هميشه ان جي سموري مواد کان پوء پيدا ڪيو ويندو آهي؛ تنهن ڪري، ان جو تسلسل نمبر ان ۾ موجود پيغامن جي ترتيب نمبرن کان وڏو يا برابر آهي.

1 جي واڌ سان هي ڪهڙي قسم جو سرڪس آهي، ۽ پوءِ ٻيو 2؟ .. مون کي شڪ آهي ته اصل معنيٰ هئي ”ACK لاءِ گهٽ سا، باقي هڪ نمبر“، پر نتيجو بلڪل صحيح نه آهي - خاص طور تي، اهو ظاهر ٿيو ته اهو موڪلي سگهجي ٿو ڪيترن تصديقون جيڪي ساڳيون آهن seq_no! ڪيئن؟ خير، مثال طور، سرور اسان کي ڪجهه موڪلي ٿو، موڪلي ٿو، ۽ اسان پاڻ خاموش آهيون، اسان صرف خدمت جي تصديق واري پيغامن سان جواب ڏيون ٿا سندس پيغام وصول ڪرڻ بابت. انهي صورت ۾، اسان جي ٻاهر نڪرڻ واري تصديق جو ساڳيو ٻاهر نڪرندڙ نمبر هوندو. جيڪڏهن توهان TCP سان واقف آهيو ۽ سوچيو ته اهو آواز هڪ چريو آهي، پر اهو لڳي ٿو ته اهو تمام جهنگلي نه آهي، ڇاڪاڻ ته TCP ۾ seq_no تبديل نٿو ڪري، ۽ تصديق ٿي وڃي ٿي seq_no ٻئي طرف - پوءِ مون کي تڪليف ڏيڻ لاءِ جلدي. تصديقون اچي رهيا آهن MTProto ڏانهن نه تي seq_no، جيئن TCP ۾، پر msg_id !

هي ڇا آهي msg_id، انهن شعبن مان سڀ کان اهم؟ پيغام جو منفرد ID، جيئن نالو مشورو ڏئي ٿو. اهو هڪ 64-بٽ نمبر جي طور تي بيان ڪيو ويو آهي، گهٽ ۾ گهٽ اهم بٽ جن ۾ وري سرور-نه-سرور جادو آهي، ۽ باقي هڪ يونڪس ٽائم اسٽيمپ آهي، جنهن ۾ جزوي حصو شامل آهي، 32 بٽ کي کاٻي طرف منتقل ڪيو ويو آهي. اهي. ٽائم اسٽيمپ في سي (۽ پيغام تمام مختلف وقتن سان سرور طرفان رد ڪيا ويندا). هن مان اهو ظاهر ٿئي ٿو ته، عام طور تي، هي هڪ سڃاڻپ ڪندڙ آهي جيڪو ڪلائنٽ لاء عالمي آهي. جڏهن ته - ياد session_id - اسان ضمانت آهيون: ڪنهن به صورت ۾ هڪ پيغام جو مطلب هڪ سيشن لاء آهي، ڪنهن ٻئي سيشن ۾ موڪلي نه ٿو سگهجي. اهو آهي، اهو ظاهر ٿئي ٿو ته اتي ئي آهي ٽي سطح - سيشن، سيشن نمبر، پيغام جي سڃاڻپ. ڇو اهڙي هڪ overcomplication، هي اسرار تمام وڏو آهي.

۽ ائين، msg_id جي ضرورت آهي…

آر پي سي: درخواستون، جواب، غلطيون. تصديقون.

جيئن توهان محسوس ڪيو هوندو، اسڪيما ۾ ڪٿي به ڪو خاص قسم يا فنڪشن نه آهي "آر پي سي جي درخواست ڪريو"، جيتوڻيڪ جواب موجود آهن. آخرڪار، اسان وٽ مواد سان لاڳاپيل پيغام آهن! اهو آهي، ڪو پيغام هڪ درخواست ٿي سگهي ٿو! يا نه هجي. سپني کان پوءِ، هر هڪ جو آهي msg_id. ۽ هتي جواب آهن:

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

هي اهو آهي جتي اهو اشارو ڪيو ويو آهي ته هي پيغام جو جواب آهي. تنهن ڪري، API جي مٿين سطح تي، توهان کي ياد رکڻو پوندو ته توهان جي درخواست ڪهڙي نمبر تي هئي - منهنجو خيال آهي ته اهو بيان ڪرڻ ضروري ناهي ته ڪم غير مطابقت رکندڙ آهي، ۽ هڪ ئي وقت ۾ ڪيتريون ئي درخواستون ٿي سگهن ٿيون، جن جا جواب ڪنهن به حڪم ۾ واپس ڪري سگهجي ٿو؟ اصولي طور تي، هن کان، ۽ غلطي جي پيغامن جهڙوڪ ڪو به ڪم ڪندڙ، هن جي پويان فن تعمير کي ڳولي سگهجي ٿو: سرور جيڪو توهان سان TCP ڪنيڪشن کي برقرار رکي ٿو هڪ فرنٽ-اينڊ بيلنس آهي، اهو درخواستن کي هدايت ڪري ٿو بيڪ اينڊس ۽ انهن کي گڏ ڪري واپس گڏ ڪري. message_id. هتي هر شي واضح، منطقي ۽ سٺي لڳي ٿي.

ها؟.. ۽ جيڪڏهن توهان ان بابت سوچيو ٿا؟ آخرڪار، آر پي سي جو جواب پاڻ وٽ پڻ هڪ فيلڊ آهي 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 ۾ رجسٽر ٿيڻ گهرجي. اسان وٽ هڪ قسم جي ٻولي آهي، صحيح؟ اسان کي اسٽرنگ مان ڪنهن دليل جي ضرورت ناهي، باقاعده اظهار ڪندا، چو.

ٻيهر، هي خدمت پيغام واري صفحي تي ناهي، پر، جيئن اڳ ۾ ئي هن منصوبي سان رواج آهي، معلومات ملي سگهي ٿي ٻئي دستاويزي صفحي تي. يا شڪ پيدا ڪرڻ. پهريون، ڏسو، ٽائپنگ/پرتن جي ڀڃڪڙي - RpcError ۾ سيڙپڪاري ڪري سگهجي ٿو RpcResult. ٻاهر ڇو نه؟ اسان ڪهڙي ڳالهه کي نظر ۾ نه رکيو آهي؟... ان حساب سان، اها ضمانت ڪٿي آهي RpcError ۾ سيڙپڪاري نه ٿي سگھي RpcResult، پر سڌو سنئون يا ڪنهن ٻئي قسم ۾ داخل ٿيو؟ ان جي کوٽ آهي req_msg_id ؟ ..

پر اچو ته خدمت جي پيغامن بابت جاري رکون. ڪلائنٽ غور ڪري سگھي ٿو ته سرور هڪ ڊگهي وقت لاء سوچي رهيو آهي، ۽ اهڙي شاندار درخواست ڪر:

rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;

ان جا ٽي ممڪن جواب آهن، هڪ ڀيرو ٻيهر تصديق واري ميڪانيزم سان ٽڪراءُ ڪندي، سمجهڻ جي ڪوشش ڪئي وڃي ته انهن کي ڇا هئڻ گهرجي (۽ انهن قسمن جي فهرست ڪهڙي آهي جن جي عام طور تي تصديق جي ضرورت نه آهي)، پڙهندڙ کي هوم ورڪ طور ڇڏيو وڃي ٿو (نوٽ: جي. ٽيليگرام ڊيسڪ ٽاپ ذريعن ۾ معلومات مڪمل نه آهي).

لت: پيغام پوسٽ اسٽيٽس

عام طور تي، TL، MTProto ۽ ٽيليگرام ۾ ڪيتريون ئي جڳھون عام طور تي ضد جو احساس ڇڏيندا آهن، پر شائستگي، حڪمت ۽ ٻين کان ٻاهر. نرم صلاحيتون اسان ان تي شائستگي سان خاموش رهياسين، ۽ ڳالهين ۾ بي حيائي کي سينسر ڪيو ويو. بهرحال، هن جڳههОگهڻو ڪري صفحي بابت پيغامن بابت پيغام مون لاءِ به جھٽڪو پيدا ڪري ٿو، جيڪو ڪافي عرصي کان نيٽ ورڪ پروٽوڪول سان ڪم ڪري رھيو آھي ۽ گھمڻ جي مختلف درجي جون سائيڪلون ڏٺيون آھن.

اهو بي ضرر طور تي شروع ٿئي ٿو، تصديق سان. اڳيون، اسان کي ٻڌايو ويندو

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 = آر پي سي سوال جيڪو پيغام ۾ موجود آهي پروسيس يا پروسيسنگ اڳ ۾ ئي مڪمل آهي
    • +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 کي ماپڻ ۽ "ونڊو" جي سائيز کي ترتيب ڏيڻ (پيغام ۾) غير تسليم ٿيل درخواستن جي تعداد جي لحاظ سان. اهو آهي، سرور جي لوڊ جو اندازو لڳائڻ لاء اهڙي هڪ سخت heuristic - اسان جي ڪيترين ئي درخواستن کي اهو هڪ ئي وقت چئجي سگهي ٿو ۽ نه وڃايو.

چڱو، اھو آھي، توھان سمجھو ٿا، صحيح؟ جيڪڏهن توهان TCP کي ٻيهر هڪ پروٽوڪول جي چوٽي تي لاڳو ڪرڻو آهي جيڪو TCP تي ڪم ڪري ٿو، اهو اشارو ڪري ٿو هڪ تمام خراب ٺهيل پروٽوڪول.

ها ها، ڇو هڪ کان وڌيڪ قطار جي ضرورت آهي، ۽ عام طور تي، هڪ اعلي سطحي API سان ڪم ڪندڙ شخص لاء ڇا مطلب آهي؟ ڏس، توهان هڪ درخواست ڪيو، توهان ان کي ترتيب ڏيو، پر اهو اڪثر ڪري ناممڪن آهي ته ان کي فوري طور تي موڪليو وڃي. ڇو؟ ڇو جو جواب هوندو msg_id، جيڪو عارضي آهيаمان هڪ ليبل آهيان، جنهن جي مقرري کي دير سان ملتوي ڪرڻ بهتر آهي - اوچتو سرور ان کي رد ڪري ڇڏيندو ڇاڪاڻ ته اسان جي ۽ ان جي وچ ۾ وقت جي ميلاپ جي ڪري (يقيناً، اسان هڪ ڪرچ ٺاهي سگهون ٿا جيڪو اسان جي وقت کي موجوده وقت کان تبديل ڪري ٿو. سرور جي جوابن مان حساب ڪيل ڊيلٽا شامل ڪندي سرور جي وقت ۾ - سرڪاري گراهڪ اهو ڪن ٿا، پر اهو طريقو خراب ۽ غلط آهي بفرنگ جي ڪري). تنهن ڪري جڏهن توهان لائبريري مان مقامي فنڪشنل ڪال سان درخواست ڪريو ٿا، پيغام هيٺين مرحلن مان گذري ٿو:

  1. ساڳي قطار ۾ بيٺو آهي ۽ انڪرپشن جي انتظار ۾ آهي.
  2. مقرر ٿيل msg_id ۽ پيغام ٻي قطار ۾ ويو - ممڪن اڳتي وڌڻ؛ ساکٽ ڏانهن موڪليو.
  3. a) سرور جواب ڏنو MsgsAck - پيغام پهچايو ويو، اسان ان کي "ٻي قطار" مان حذف ڪريون ٿا.
    ب) يا ان جي برعڪس، هن کي ڪجهه پسند نه آيو، هن جواب ڏنو badmsg - اسان "ٻي قطار" مان ٻيهر موڪليندا آهيون
    ج) ڪجھ به معلوم نه آهي، اهو ضروري آهي ته پيغام کي ٻي قطار مان ٻيهر موڪليو وڃي - پر اهو معلوم ناهي ته ڪڏهن.
  4. سرور آخر جواب ڏنو RpcResult - حقيقي جواب (يا غلطي) - نه رڳو پهچايو ويو، پر پروسيس پڻ.

شايد ايڏو، ڪنٽينرز جو استعمال جزوي طور مسئلو حل ڪري سگھي ٿو. اهو آهي جڏهن پيغامن جو هڪ گروپ هڪ ۾ ڀريل آهي، ۽ سرور هڪ ئي وقت سڀني کي هڪ اعتراف سان جواب ڏنو، هڪ سان msg_id. پر هو هن پيڪ کي به رد ڪري ڇڏيندو، جيڪڏهن ڪجهه غلط ٿي ويو ته، پڻ سڄي شيء.

۽ هن نقطي تي، غير ٽيڪنيڪل خيالات راند ۾ اچن ٿا. تجربي مان، اسان ڪيتريون ئي ڪچيون ڏٺيون آهن، ۽ ان کان علاوه، هاڻي اسان خراب مشوري ۽ فن تعمير جا وڌيڪ مثال ڏسي سگهنداسين - اهڙين حالتن ۾، ڇا اهو قابل اعتماد آهي ۽ اهڙي فيصلا ڪرڻ جي قابل آهي؟ سوال بيان بازي آهي (يقيناً نه).

اسان ڇا ڳالهائي رهيا آهيون؟ جيڪڏهن موضوع تي "پيغام جي باري ۾ لت پيغام" توهان اڃا تائين اعتراضن سان اندازو لڳائي سگهو ٿا جهڙوڪ "توهان بيوقوف آهيو، توهان اسان جي شاندار خيال کي نه سمجهي!" (تنهنڪري پهريان دستاويز لکو، جيئن عام ماڻهن کي گهرجي، منطقي ۽ پيڪٽ ايڪسچينج مثالن سان، پوءِ ڳالهائينداسين)، پوءِ ٽائمنگ / ٽائم آئوٽ هڪ خالص عملي ۽ مخصوص مسئلو آهي، هتي هر شيءِ گهڻي وقت کان معلوم ٿي چڪي آهي. پر ڇا دستاويز اسان کي وقت جي باري ۾ ٻڌائي ٿو؟

سرور عام طور تي قبول ڪري ٿو پيغام جي وصولي کي ڪلائنٽ کان (عام طور تي، هڪ آر پي سي سوال) هڪ آر پي سي جواب استعمال ڪندي. جيڪڏهن هڪ جواب هڪ ڊگهو وقت اچي رهيو آهي، هڪ سرور پهريون ڀيرو هڪ رسيد جي تصديق موڪلي سگهي ٿو، ۽ ڪجهه دير بعد، آر پي سي جواب پاڻ.

هڪ ڪلائنٽ عام طور تي سرور کان پيغام جي وصولي کي تسليم ڪري ٿو (عام طور تي، هڪ آر پي سي جواب) ايندڙ آر پي سي سوال ۾ هڪ اعتراف شامل ڪندي جيڪڏهن اهو تمام دير سان منتقل نه ڪيو ويو آهي (جيڪڏهن اهو ٺاهيل آهي، چئو، رسيد جي پٺيان 60-120 سيڪنڊ سرور مان هڪ پيغام). بهرحال، جيڪڏهن گهڻي عرصي تائين سرور ڏانهن پيغام موڪلڻ جو ڪو سبب ناهي يا جيڪڏهن سرور مان اڻ ڄاتل پيغامن جو وڏو تعداد آهي (چئو، 16 کان مٿي)، ڪلائنٽ هڪ اسٽينڊ اڪيلو اعتراف منتقل ڪري ٿو.

... مان ترجمو ڪريان ٿو: اسان پاڻ نه ٿا ڄاڻون ته اهو ڪيترو ۽ ڪيئن ضروري آهي، چڱو، اچو ته اندازو لڳايو ته ان کي ائين ڪرڻ ڏيو.

۽ پنگ بابت:

پنگ پيغام (پنگ/پونگ)

ping#7abe77ec ping_id:long = Pong;

جواب عام طور تي ساڳئي ڪنيڪشن ڏانهن موٽايو ويندو آهي:

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

انهن پيغامن کي تسليم ڪرڻ جي ضرورت ناهي. هڪ پونگ صرف هڪ پنگ جي جواب ۾ منتقل ڪيو ويندو آهي جڏهن ته هڪ پنگ ٻنهي طرفن کان شروع ڪري سگهجي ٿو.

ملتوي ڪنيڪشن بند ڪرڻ + PING

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

پنگ وانگر ڪم ڪري ٿو. ان کان علاوه، هي موصول ٿيڻ کان پوء، سرور هڪ ٽائمر شروع ڪري ٿو جيڪو موجوده ڪنيڪشن کي بند ڪري ڇڏيندو disconnect_delay سيڪنڊن بعد جيستائين اهو ساڳئي قسم جو هڪ نئون پيغام وصول ڪري ٿو جيڪو خودڪار طور تي سڀني پوئين ٽائمرز کي ري سيٽ ڪري ٿو. جيڪڏهن ڪلائنٽ هر 60 سيڪنڊن ۾ هڪ ڀيرو اهي پنگ موڪلي ٿو، مثال طور، اهو سيٽ ڪري سگھي ٿو disconnect_delay برابر 75 سيڪنڊ.

ڇا تون عقل کان ٻاهر آهين؟! 60 سيڪنڊن ۾، ٽرين اسٽيشن ۾ داخل ٿيندي، ڇڏيندي ۽ مسافرن کي کڻڻ، ۽ ٻيهر سرنگ ۾ رابطي کي وڃائي ڇڏيندو. 120 سيڪنڊن ۾، جڏهن توهان ٻاهر آهيو، هو ٻئي ڏانهن ايندو، ۽ ڪنيڪشن گهڻو ڪري ڀڄي ويندو. خير، اهو واضح آهي ته ٽنگون ڪٿان وڌنديون آهن - “مون هڪ رنج ٻڌو، پر مون کي خبر ناهي ته اهو ڪٿي آهي”، اتي ناگل جو الگورٿم ۽ TCP_NODELAY آپشن آهي، جيڪو انٽرايڪٽو ڪم لاءِ هو. پر، معاف ڪجو، دير ڪريو ان جي ڊفالٽ قيمت - 200 مليسيڪنڊ جيڪڏھن توھان چاھيو ٿا ته اھڙي ئي ڪا شيءِ پيش ڪرڻ ۽ محفوظ ڪرڻ چاھيو پئڪيٽ جي ممڪن جوڙي تي - چڱو، ان کي بند ڪريو، گھٽ ۾ گھٽ 5 سيڪنڊن لاءِ، يا جيڪو به پيغام جو ٽائم آئوٽ ”يوزر ٽائيپ ڪري رھيو آھي...“ ھاڻي برابر آھي. پر وڌيڪ نه.

۽ آخرڪار، پنگ. اهو آهي، هڪ TCP ڪنيڪشن جي جاندار جي جانچ ڪندي. اها مذاق آهي، پر اٽڪل 10 سال اڳ مون اسان جي فيڪلٽي جي هاسٽل جي ميسينجر جي باري ۾ هڪ نازڪ متن لکيو هو - اتي مصنفن پڻ ڪلائنٽ کان سرور کي پنگ ڪيو، ۽ ان جي برعڪس نه. پر ٽئين سال جي شاگردن هڪ شيء آهي، ۽ هڪ بين الاقوامي آفيس ٻي آهي، صحيح؟ ..

پهريون، هڪ ننڍڙو تعليمي پروگرام. هڪ TCP ڪنيڪشن، پيٽ جي بدلي جي غير موجودگي ۾، هفتي تائين رهي سگهي ٿو. هي ٻئي سٺو ۽ خراب آهي، مقصد تي منحصر آهي. خير، جيڪڏهن توهان وٽ سرور سان هڪ SSH ڪنيڪشن کليل هو، توهان پنهنجي ڪمپيوٽر مان اٿيو، پاور روٽر کي ريبوٽ ڪيو، پنهنجي جاء تي واپس آيو - هن سرور ذريعي سيشن نه ٽوڙيو (ڪجهه به ٽائيپ نه ڪيو، ڪو به پيڪيٽ نه هئا)، آسان. اهو خراب آهي جيڪڏهن سرور تي هزارين ڪلائنٽ آهن، هر هڪ وسيلا وٺي ٿو (هيلو پوسٽ گريس!)، ۽ ڪلائنٽ ميزبان شايد گهڻو وقت اڳ ريبوٽ ڪيو آهي - پر اسان ان بابت نه ڄاڻندا سين.

چيٽ/IM سسٽم ٻئي ڪيس سان تعلق رکن ٿا ٻئي لاءِ، اضافي سبب - آن لائين اسٽيٽس. جيڪڏهن استعمال ڪندڙ "بند ٿي ويو"، ان جي باري ۾ سندس ڳالهائيندڙن کي خبر ڪرڻ ضروري آهي. ٻي صورت ۾، ڪا غلطي ٿيندي جيڪا جابر جي ٺاهيندڙن ڪئي (۽ 20 سالن تائين درست ڪئي وئي) - استعمال ڪندڙ کان ڌار ٿي ويو، پر اهي هن کي پيغام لکڻ جاري رکندا آهن، اهو يقين آهي ته هو آن لائن آهي (جيڪي پڻ انهن چند منٽن ۾ مڪمل طور تي گم ٿي ويا آهن. وقفو دريافت ڪيو ويو). نه، TCP_KEEPALIVE آپشن، جيڪو گھڻا ماڻھو نه ٿا سمجھن ته TCP ٽائمر ڪيئن ڪم ڪن ٿا، ڪٿي به پاپ ٿي وڃن ٿا (جهنگلي قدرن کي ترتيب ڏيڻ سان، جيئن ڏھن سيڪنڊن جي)، ھتي مدد نه ڪندو - توھان کي پڪ ڪرڻ جي ضرورت آھي ته نه رڳو او ايس ڪرنل جو. صارف جي مشين زنده آهي، پر عام طور تي ڪم ڪري ٿي، جواب ڏيڻ جي قابل، ۽ ايپليڪيشن پاڻ (ڇا توهان سوچيو ته اهو منجمد نه ٿي سگهي؟ Ubuntu 18.04 تي ٽيليگرام ڊيسڪ ٽاپ مون لاء بار بار تباهه ٿي چڪو آهي).

انهي ڪري توهان کي پنگ ڪرڻ گهرجي سرور ڪلائنٽ، ۽ نه ان جي برعڪس - جيڪڏهن ڪلائنٽ اهو ڪري ٿو، جڏهن ڪنيڪشن ڀڄي ويندو آهي، پنگ نه پهچايو ويندو، مقصد حاصل نه ڪيو ويندو.

۽ اسان ٽيليگرام ۾ ڇا ٿا ڏسو؟ هر شيء بلڪل سامهون آهي! خير، i.e. رسمي طور تي، يقينا، ٻنهي پاسن هڪ ٻئي کي پنگ ڪري سگهن ٿا. عملي طور تي، گراهڪ هڪ ڪڇ استعمال ڪندا آهن ping_delay_disconnect، جيڪو سرور تي ٽائمر کي ڪڪ ڪري ٿو. خير، معاف ڪجو، اهو ڪلائنٽ جو ڪاروبار ناهي ته اهو فيصلو ڪري ته هو پنگ کانسواءِ اتي ڪيترو وقت رهڻ چاهي ٿو. سرور، ان جي لوڊ تي ٻڌل، بهتر ڄاڻي ٿو. پر، يقينا، جيڪڏهن توهان وسيلن لاء افسوس محسوس نه ڪيو، ته پوء برائي Pinocchio پاڻ آهن، ۽ ڪرچ هيٺ اچي ويندا ...

اهو ڪيئن ٺهيل هجڻ گهرجي؟

مان سمجهان ٿو ته مٿين حقيقتن مان واضح طور تي ظاهر ٿئي ٿو ته ٽيليگرام / VKontakte ٽيم جي ڪمپيوٽر نيٽ ورڪ جي ٽرانسپورٽ (۽ هيٺين) سطح جي ميدان ۾ نه تمام اعلي صلاحيت ۽ لاڳاپيل معاملن ۾ انهن جي گهٽ قابليت.

اهو ايترو پيچيده ڇو ٿي ويو، ۽ ڪيئن ٽيليگرام آرڪيٽيڪٽس اعتراض ڪرڻ جي ڪوشش ڪري سگهي ٿو؟ حقيقت اها آهي ته انهن هڪ سيشن ٺاهڻ جي ڪوشش ڪئي جيڪا بچي وڃي TCP ڪنيڪشن جي ڀڃڪڙي، اهو آهي، جيڪو اسان هاڻي نه پهچايو آهي، اسان بعد ۾ پهچائينداسين. انهن شايد UDP ٽرانسپورٽ ٺاهڻ جي ڪوشش ڪئي، جيتوڻيڪ اهي مشڪلاتن ۾ ڀڄي ويا ۽ ان کي ڇڏي ڏنو (اهو ئي سبب آهي ته دستاويز خالي آهي - ان جي باري ۾ ڪجهه به نه هو). پر سمجھ ۾ نه اچڻ جي ڪري عام طور تي نيٽ ورڪ ڪيئن ۽ خاص طور تي TCP ڪم ڪري ٿو، جتي توھان ان تي ڀروسو ڪري سگھو ٿا، ۽ ڪٿي توھان کي اھو پاڻ ڪرڻ جي ضرورت آھي (۽ ڪيئن)، ۽ ھن کي ڪرپٽوگرافيءَ سان گڏ ڪرڻ جي ڪوشش “ٻن جو ھڪڙو شاٽ. پکي هڪ پٿر سان“ - اهڙو لاش ٻاهر نڪتو.

اهو ڪيئن ٿيڻ گهرجي ها؟ ان حقيقت جي بنياد تي msg_id هڪ ٽائم اسٽيمپ آهي جيڪو cryptographically ضروري آهي ريپلي حملن کي روڪڻ لاءِ، ان سان هڪ منفرد سڃاڻپ ڪندڙ فنڪشن کي ڳنڍڻ هڪ غلطي آهي. تنهن ڪري، موجوده فن تعمير کي سختي سان تبديل ڪرڻ کان سواء (جڏهن تازه ڪاري موضوع ٺهيل آهي، هي پوسٽن جي هن سيريز جي ٻئي حصي لاء هڪ اعلي سطحي API موضوع آهي)، هڪ کي ڪرڻو پوندو:

  1. سرور جيڪو ڪلائنٽ سان TCP ڪنيڪشن رکي ٿو ذميواري وٺندو آهي - جيڪڏهن توهان ساکٽ مان ڪڍي ڇڏيو، جيڪڏهن توهان مهرباني ڪري، تصديق ڪريو، عمل ڪريو يا غلطي واپس ڪريو، ڪو به نقصان نه. پوءِ تصديق id جي ویکٹر نه آهي، پر صرف "آخري حاصل ڪيل seq_no" - صرف هڪ نمبر، جيئن TCP ۾ (ٻه نمبر - توهان جو پنهنجو seq ۽ تصديق ٿيل). اسان هميشه سيشن ۾ آهيون، ڇا اسان نه آهيون؟
  2. ريپلي حملن کي روڪڻ لاءِ ٽائم اسٽيمپ هڪ الڳ ميدان بڻجي ويندو آهي، هڪ لا نانس. چيڪ ڪيو ويو، پر ٻيو ڪجھ به متاثر نه ٿيو. ڪافي ۽ uint32 - جيڪڏهن اسان جو لوڻ گهٽ ۾ گهٽ هر اڌ ڏينهن ۾ تبديل ٿئي ٿو، اسان 16 بٽ کي موجوده وقت جي انٽيجر واري حصي جي هيٺين بٽن ڏانهن مختص ڪري سگهون ٿا، باقي - هڪ سيڪنڊ جي جزوي حصي ڏانهن (جيئن اهو هاڻي آهي).
  3. واپس ورتو ويو msg_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 جي مٿان؟

compact serialization. هن ڊيٽا جي جوڙجڪ کي ڏسي، JSON سان ملندڙ جلندڙ، اهو ياد اچي ٿو ته ان جا بائنري مختلف قسم آهن. اچو ته MsgPack کي غير مناسب طور تي وسعت واري طور تي نشان لڳايو، پر اتي موجود آهي، مثال طور، CBOR - طريقي سان، معيار بيان ڪيل آهي. آر ايف سي سي ايم ايس. اهو قابل ذڪر آهي ته حقيقت اها آهي ته اها وضاحت ڪري ٿي ٽيگ، هڪ توسيع ميڪانيزم جي طور تي، ۽ وچ ۾ اڳ ۾ ئي معياري هتي آهن:

  • 25 + 256 - نقل واري لائينن کي ليڪ نمبر جي حوالي سان تبديل ڪرڻ، اهڙي سستي ڪمپريشن جو طريقو
  • 26 - سيريل ٿيل پرل اعتراض ڪلاس جي نالي ۽ تعمير ڪندڙ دليلن سان
  • 27 - قسم جي نالي ۽ تعمير ڪندڙ دليلن سان سيريل ٿيل ٻولي-آزاد اعتراض

خير، مون ڪوشش ڪئي ساڳي ڊيٽا کي سيريل ڪرڻ جي TL ۽ CBOR ۾ پيڪنگنگ سان گڏ اسٽرنگز ۽ شيون فعال. نتيجو هڪ ميگا بائيٽ کان ڪٿي CBOR جي حق ۾ مختلف ٿيڻ لڳو:

cborlen=1039673 tl_len=1095092

۽ ائين، نتيجو: ڪافي سادو فارميٽ آھن جيڪي مطابقت پذير ڪارڪردگي سان، مطابقت پذير ناڪامي يا نامعلوم سڃاڻپ ڪندڙ مسئلي جي تابع نه آھن.

فاسٽ ڪنيڪشن قائم ڪرڻ. ان جو مطلب آهي صفر RTT ٻيهر ڪنيڪشن کان پوءِ (جڏهن ڪيئي اڳ ۾ ئي هڪ ڀيرو ٺاهي وئي آهي) - لاڳو ٿئي ٿو پهرين ايم ٽي پروٽو پيغام کان، پر ڪجهه تحفظات سان - اهي ساڳيا لوڻ ۾ اچي ويا، سيشن خراب نه ٿيو، وغيره. بدلي ۾ TLS اسان کي ڇا پيش ڪري ٿو؟ لاڳاپيل اقتباس:

TLS ۾ PFS استعمال ڪرڻ وقت، TLS سيشن ٽڪيٽ (آر ايف سي سي ايم ايس) انڪرپٽ ٿيل سيشن کي ٻيهر شروع ڪرڻ کان سواءِ چاٻين جي ٻيهر ڳالهه ٻولهه ڪرڻ ۽ سرور تي اهم معلومات محفوظ ڪرڻ کان سواءِ. جڏهن پهريون ڪنيڪشن کولڻ ۽ ڪنيڪشن ٺاهيندي، سرور ڪنيڪشن جي حالت کي انڪرپٽ ڪري ٿو ۽ ان کي ڪلائنٽ ڏانهن موڪلي ٿو (سيشن ٽڪيٽ جي صورت ۾). ان مطابق، جڏهن ڪنيڪشن ٻيهر شروع ڪيو ويندو آهي، ڪلائنٽ هڪ سيشن ٽڪيٽ موڪليندو آهي، جنهن ۾ ٻين شين جي وچ ۾، سيشن ڪيچ واپس سرور ڏانهن. ٽڪيٽ بذات خود هڪ عارضي چيڪ (سيشن ٽڪيٽ ڪيچ) سان انڪريپٽ ٿيل آهي، جيڪا سرور تي محفوظ ڪئي ويندي آهي ۽ لازمي طور تي سڀني فرنٽ اينڊ سرورز تي ورهائجي ويندي آهي جيڪي ڪلسٽر ٿيل حلن ۾ SSL کي سنڀاليندا آهن.[10] ان ڪري، سيشن ٽڪيٽ جو تعارف PFS جي خلاف ورزي ڪري سگھي ٿو جيڪڏهن عارضي سرور چابيون سمجھوتيون ڪيون وڃن، مثال طور، جڏھن اھي ڊگھي وقت لاءِ ذخيرو ٿيل آھن (OpenSSL، nginx، Apache by default انھن کي پوري وقت لاءِ اسٽور ڪريو پروگرام ھلڻ وقت؛ مشهور سائيٽون ڪيترن ئي ڪلاڪن تائين، ڏينهن تائين ڪنجي استعمال ڪريو).

هتي RTT صفر نه آهي، توهان کي گهٽ ۾ گهٽ ڪلائنٽ هيلو ۽ سرور هيلو کي مٽائڻ جي ضرورت آهي، جنهن کان پوء، مڪمل طور تي، ڪلائنٽ اڳ ۾ ئي ڊيٽا موڪلي سگهي ٿو. پر هتي اهو ياد رکڻ گهرجي ته اسان وٽ ويب نه آهي، جنهن ۾ نوان کوليل ڪنيڪشن آهن، پر هڪ ميسينجر آهي، جنهن جو ڪنيڪشن اڪثر ڪري هڪ يا گهٽ ۾ گهٽ ڊگهو هوندو آهي، نسبتا مختصر ويب پيجز لاءِ درخواستون - سڀ ڪجهه آهي. اندر ملٽي پلڪس. اهو آهي، اهو ڪافي قابل قبول آهي، جيڪڏهن اسان هڪ تمام خراب سب وي سيڪشن ۾ نه آيا آهيون.

ٻيو ڪجهه وساريو؟ تبصرن ۾ لکو.

جاري رکڻ گهرجي!

پوسٽن جي هن سلسلي جي ٻئي حصي ۾، اسان ٽيڪنيڪل مسئلن جي بدران تنظيمي مسئلن تي غور ڪنداسين - نقطه نظر، نظريا، انٽرفيس، استعمال ڪندڙن ڏانهن رويو، وغيره. بهرحال، ٽيڪنيڪل معلومات جي بنياد تي جيڪا هتي پيش ڪئي وئي هئي.

ٽيون حصو ٽيڪنيڪل جزو / ترقي جي تجربي جو تجزيو جاري رکندو. توھان خاص طور تي سکندا:

  • TL-قسم جي مختلف قسمن سان پنڊمونيم جو تسلسل
  • چينلز ۽ سپر گروپن بابت اڻڄاتل شيون
  • dialogs کان وڌيڪ خراب آهي roster کان
  • مطلق بمقابله لاڳاپو پيغام ايڊريسنگ بابت
  • تصوير ۽ تصوير جي وچ ۾ ڇا فرق آهي
  • ڪيئن emoji italicized متن سان مداخلت

۽ ٻيون ڪچيون! ڏسندا رهو!

جو ذريعو: www.habr.com

تبصرو شامل ڪريو