ටෙලිග්‍රාම් හි ප්‍රොටෝකෝලය සහ සංවිධානාත්මක ප්‍රවේශයන් විවේචනය කිරීම. 1 කොටස, තාක්ෂණික: මුල සිටම සේවාදායකයකු ලිවීමේ අත්දැකීම - TL, MT

මෑතකදී, ටෙලිග්‍රාම් කොතරම් හොඳද, ඩුරොව් සහෝදරයන් ජාල පද්ධති ගොඩනැගීමේ දී කෙතරම් දක්ෂ හා පළපුරුදුද, යනාදිය ගැන පෝස්ට් හබ්‍රේ හි නිතර පෙනෙන්නට පටන් ගෙන තිබේ. ඒ අතරම, ඉතා සුළු පිරිසක් සැබවින්ම තාක්ෂණික උපාංගයේ ගිලී ඇත - උපරිම වශයෙන්, ඔවුන් JSON මත පදනම් වූ තරමක් සරල (සහ MTProto ට වඩා බෙහෙවින් වෙනස්) Bot API භාවිතා කරයි, සහ සාමාන්‍යයෙන් පිළිගනිති. ඇදහිල්ල මත පණිවිඩකරු වටා කැරකෙන සියලුම ප්‍රශංසා සහ PR. වසර එකහමාරකට පමණ පෙර, Eshelon NGO හි මගේ සගයා Vasily (අවාසනාවකට මෙන්, Habré පිළිබඳ ඔහුගේ ගිණුම කෙටුම්පත සමඟ මකා දමා ඇත) Perl හි මුල සිටම ඔහුගේම ටෙලිග්‍රාම් සේවාදායකයා ලිවීමට පටන් ගත් අතර පසුව මෙම රේඛාවල කතුවරයා සම්බන්ධ විය. ඇයි පර්ල්, සමහරු වහාම අසයි? මක්නිසාද යත් එවැනි ව්‍යාපෘති දැනටමත් වෙනත් භාෂාවලින් පවතින බැවිනි.ඇත්ත වශයෙන්ම, කාරණය මෙය නොවේ, නොමැති වෙනත් භාෂාවක් තිබිය හැකිය. සූදානම් පුස්තකාලය, සහ ඒ අනුව කතුවරයා සෑම පැත්තකින්ම යා යුතුය මුල සිට. එපමනක් නොව, ගුප්තකේතනය යනු විශ්වාසය පිළිබඳ කාරණයකි, නමුත් සත්‍යාපනය කරන්න. ආරක්ෂාව අරමුණු කරගත් නිෂ්පාදනයක් සමඟ, ඔබට නිෂ්පාදකයාගේ සූදානම් කළ පුස්තකාලයක් මත විශ්වාසය තැබිය නොහැකි අතර එය අන්ධ ලෙස විශ්වාස කළ නොහැක (කෙසේ වෙතත්, මෙය දෙවන කොටස සඳහා මාතෘකාවකි). මේ මොහොතේ, පුස්තකාලය "සාමාන්‍ය" මට්ටමින් හොඳින් ක්‍රියා කරයි (ඕනෑම API ඉල්ලීමක් කිරීමට ඔබට ඉඩ සලසයි).

කෙසේ වෙතත්, මෙම පළ කිරීම් මාලාවේ බොහෝ ගුප්ත ලේඛන හෝ ගණිතයක් නොතිබෙනු ඇත. නමුත් වෙනත් බොහෝ තාක්ෂණික විස්තර සහ වාස්තුවිද්‍යාත්මක අත්වාරු (මුල සිට ලියන්නේ නැති නමුත් ඕනෑම භාෂාවකින් පුස්තකාලය භාවිතා කරන අයටද ප්‍රයෝජනවත් වනු ඇත). එබැවින්, ප්රධාන ඉලක්කය වූයේ සේවාදායකයා මුල සිටම ක්රියාත්මක කිරීමට උත්සාහ කිරීමයි නිල ලියකියවිලි අනුව. එනම්, නිල සේවාදායකයින්ගේ ප්‍රභව කේතය වසා ඇති බව උපකල්පනය කරමු (නැවතත්, දෙවන කොටසේදී මෙය සත්‍ය බව යන මාතෘකාව අපි වඩාත් විස්තරාත්මකව ආවරණය කරමු. සිදුවෙනවා ඉතින්), නමුත්, පැරණි දිනවල මෙන්, උදාහරණයක් ලෙස, RFC වැනි ප්‍රමිතියක් තිබේ - පිරිවිතරයන්ට අනුව පමණක් සේවාදායකයෙකු ලිවීමට හැකිද, මූලාශ්‍ර කේතය දෙස “බැලීමකින් තොරව”, එය නිල (ටෙලිග්‍රාම් ඩෙස්ක්ටොප්, ජංගම), හෝ නිල නොවන Telethon?

අන්තර්ගත වගුව:

ලියකියවිලි... ඒක තියෙනවා නේද? ඇත්තද?..

මෙම ලිපිය සඳහා සටහන් කොටස් පසුගිය ගිම්හානයේදී එකතු කිරීමට පටන් ගත්තේය. මේ කාලය පුරාම නිල වෙබ් අඩවියේ https://core.telegram.org ලේඛන ලේඛනය 23 වන ස්ථරයේ, i.e. 2014 දී කොහේ හරි හිරවෙලා (මතක තියාගන්න, එදා නාලිකා පවා තිබුණේ නැහැ?). ඇත්ත වශයෙන්ම, න්‍යායාත්මකව, මෙය අපට 2014 දී ක්‍රියාකාරීත්වය සහිත සේවාදායකයෙකු ක්‍රියාත්මක කිරීමට ඉඩ දිය යුතුය. නමුත් මෙම තත්වය තුළ පවා, ලේඛනගත කිරීම, පළමුව, අසම්පූර්ණ වූ අතර, දෙවනුව, ස්ථානවල එය පරස්පර විය. මාසයකට පමණ පෙර, 2019 සැප්තැම්බර් මාසයේදී, එය විය අහම්බෙන් සම්පූර්ණයෙන්ම මෑත කාලීන 105 ස්ථරය සඳහා, වෙබ් අඩවියේ ලේඛනවල විශාල යාවත්කාලීන කිරීමක් ඇති බව සොයා ගන්නා ලදී, දැන් සියල්ල නැවත කියවිය යුතු බව සටහනක් සමඟින්. ඇත්ත වශයෙන්ම, බොහෝ ලිපි සංශෝධනය කරන ලද නමුත් බොහෝ ලිපි නොවෙනස්ව පැවතුනි. එමනිසා, ලේඛනගත කිරීම පිළිබඳ පහත විවේචනය කියවන විට, මෙම සමහර දේවල් තවදුරටත් අදාළ නොවන නමුත් සමහර ඒවා තවමත් ඉතා හොඳ බව මතක තබා ගත යුතුය. ඇත්ත වශයෙන්ම, නූතන ලෝකයේ වසර 5 ක් දිගු කාලයක් පමණක් නොව හරිම බිසී ගොඩක්. එම කාලවල සිට (විශේෂයෙන් ඔබ එතැන් සිට ඉවතලන සහ පුනර්ජීවනය කරන ලද geochat අඩවි සැලකිල්ලට නොගන්නේ නම්), යෝජනා ක්රමයේ API ක්රම ගණන සියයේ සිට දෙසිය පනහකට වඩා වැඩි වී ඇත!

තරුණ කතුවරයෙකු ලෙස ආරම්භ කළ යුත්තේ කොතැනින්ද?

ඔබ මුල සිට ලිවීම හෝ භාවිතා කිරීම වැදගත් නොවේ, උදාහරණයක් ලෙස, සූදානම් කළ පුස්තකාල වැනි පයිතන් සඳහා ටෙලිතන් හෝ PHP සඳහා මැඩ්ලයින්, ඕනෑම අවස්ථාවක, ඔබට මුලින්ම අවශ්ය වනු ඇත ඔබගේ අයදුම්පත ලියාපදිංචි කරන්න - පරාමිතීන් ලබා ගන්න api_id и api_hash (VKontakte API සමඟ වැඩ කළ අය වහාම තේරුම් ගනී) සේවාදායකයා විසින් යෙදුම හඳුනා ගනු ඇත. මෙය කරන්න ඕනේ නීත්‍යානුකූල හේතූන් මත එය කරන්න, නමුත් පුස්තකාල කතුවරුන්ට එය දෙවන කොටසේ ප්‍රකාශයට පත් කළ නොහැක්කේ මන්දැයි අපි වැඩි විස්තර කතා කරමු. පරීක්ෂණ අගයන් ගැන ඔබ සෑහීමකට පත් විය හැකිය, ඒවා ඉතා සීමිත වුවද - දැන් ඔබට ලියාපදිංචි විය හැකිය එකක් පමණයි යෙදුම, ඒ නිසා ඉක්මන් නොවන්න.

දැන්, තාක්ෂණික දෘෂ්ටි කෝණයකින්, ලියාපදිංචි වීමෙන් පසුව, ලේඛනගත කිරීම, ප්රොටෝකෝලය ආදිය සඳහා යාවත්කාලීන කිරීම් පිළිබඳව ටෙලිග්රාම් වෙතින් දැනුම්දීම් ලැබිය යුතු බව අප උනන්දු විය යුතුය. එනම්, නැව් තටාක සහිත වෙබ් අඩවිය සරලව අතහැර දමා සේවාදායකයින් සෑදීමට පටන් ගත් අය සමඟ විශේෂයෙන් වැඩ කරන බව කෙනෙකුට උපකල්පනය කළ හැකිය. එය වඩාත් පහසු ය. නමුත් නැහැ, එහෙම දෙයක් නිරීක්ෂණය වුණේ නැහැ, කිසිම තොරතුරක් ආවේ නැහැ.

ඔබ මුල සිටම ලියන්නේ නම්, ලබාගත් පරාමිති භාවිතා කිරීම ඇත්ත වශයෙන්ම බොහෝ දුරයි. වුවද https://core.telegram.org/ සහ මුලින්ම ආරම්භ කිරීම තුළ ඔවුන් ගැන කතා කරයි, ඇත්ත වශයෙන්ම, ඔබ මුලින්ම ක්රියාත්මක කිරීමට සිදු වනු ඇත MTPproto ප්රොටෝකෝලය - නමුත් ඔබ විශ්වාස කළා නම් OSI ආකෘතියට අනුව පිරිසැලසුම ප්රොටෝකෝලය පිළිබඳ සාමාන්ය විස්තරයක් සඳහා පිටුව අවසානයේ, එය සම්පූර්ණයෙන්ම නිෂ්ඵල වේ.

ඇත්ත වශයෙන්ම, MTProto වලට පෙර සහ පසුව, එකවර මට්ටම් කිහිපයකින් (OS kernel හි වැඩ කරන විදේශීය ජාලකරුවන් පවසන පරිදි, ස්ථර උල්ලංඝනය කිරීම), විශාල, වේදනාකාරී සහ භයානක මාතෘකාවක් මාර්ගයට වැටෙනු ඇත.

ද්විමය අනුක්‍රමිකකරණය: TL (වර්ගය භාෂාව) සහ එහි යෝජනා ක්‍රමය, සහ ස්ථර, සහ තවත් බොහෝ භයානක වචන

මෙම මාතෘකාව, ඇත්ත වශයෙන්ම, ටෙලිග්‍රාම් හි ගැටළු සඳහා යතුරයි. ඔබ එය සොයා බැලීමට උත්සාහ කළහොත් භයානක වචන රාශියක් ඇත.

ඉතින්, මෙන්න රූප සටහන. මෙම වචනය ඔබේ මතකයට නැඟෙන්නේ නම්, මෙසේ කියන්න. JSON යෝජනා ක්රමය, ඔබ නිවැරදිව සිතුවා. ඉලක්කය එකම ය: සම්ප්‍රේෂණය කළ හැකි දත්ත කට්ටලයක් විස්තර කිරීමට යම් භාෂාවක්. මෙහි සමානකම් අවසන් වේ. පිටුවෙන් නම් MTPproto ප්රොටෝකෝලය, හෝ නිල සේවාදායකයාගේ මූලාශ්‍ර ගසෙන්, අපි යම් යෝජනා ක්‍රමයක් විවෘත කිරීමට උත්සාහ කරමු, අපට මෙවැනි දෙයක් පෙනෙනු ඇත:

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

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

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

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

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

---functions---

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

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

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

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

මෙය පළමු වරට දකින පුද්ගලයෙකුට ලියා ඇති දෙයින් කොටසක් පමණක් හඳුනා ගැනීමට හැකි වනු ඇත - හොඳයි, මේවා පෙනෙන විදිහට ව්‍යුහයන් (නම තිබුණත්, වමේ හෝ දකුණේ?), ඒවායේ ක්ෂේත්‍ර තිබේ, ඉන් පසුව මහා බඩවැලකින් පසු වර්ගයක් අනුගමනය කරයි... බොහෝ විට. මෙහි කෝණ වරහන් තුළ බොහෝ විට C++ වැනි සැකිලි ඇත (ඇත්ත වශයෙන්ම, ඇත්තෙන්ම නැහැ) අනෙක් සියලුම සංකේත වලින් අදහස් කරන්නේ කුමක්ද, ප්‍රශ්න ලකුණු, විශ්මයාර්ථ ලකුණු, ප්‍රතිශත, හෑෂ් ලකුණු (සහ පැහැදිලිවම ඒවා විවිධ ස්ථානවල විවිධ දේ අදහස් කරයි), සමහර විට පවතින සහ සමහර විට නැති, ෂඩාස්රාකාර සංඛ්‍යා - සහ වඩාත්ම වැදගත් ලෙස, මෙයින් ලබා ගන්නේ කෙසේද නිවැරදි එක (සේවාදායකය විසින් ප්‍රතික්ෂේප නොකරනු ලබන) බයිට් ප්‍රවාහය? ඔබට ලේඛන කියවීමට සිදුවේ (ඔව්, ආසන්නයේ JSON අනුවාදයේ යෝජනා ක්‍රමයට සබැඳි ඇත - නමුත් එයින් එය පැහැදිලි නොවේ).

පිටුව විවෘත කරන්න ද්විමය දත්ත අනුක්‍රමිකකරණය සහ හතු සහ විවික්ත ගණිතයේ ඉන්ද්‍රජාලික ලෝකයට කිමිදෙන්න, 4 වන වසරේ මාටන් හා සමාන දෙයක්. හෝඩිය, වර්ගය, අගය, සංයෝජන, ක්‍රියාකාරී සංයෝජන, සාමාන්‍ය ස්වරූපය, සංයුක්ත වර්ගය, බහුරූපී වර්ගය... සහ ඒ සියල්ල පළමු පිටුව පමණි! ඊළඟට ඔබ බලා සිටී TL භාෂාව, එය දැනටමත් නොවැදගත් ඉල්ලීමක් සහ ප්‍රතිචාරයක් පිළිබඳ උදාහරණයක් අඩංගු වුවද, වඩාත් සාමාන්‍ය අවස්ථාවන්ට කිසිසේත් පිළිතුරක් ලබා නොදේ, එයින් අදහස් කරන්නේ ඔබට රුසියානු භාෂාවෙන් ඉංග්‍රීසි භාෂාවට පරිවර්තනය කරන ලද ගණිතය නැවත කියවීමට තවත් අටක් කාවැද්දීමට සිදුවන බවයි. පිටු!

ක්‍රියාකාරී භාෂා සහ ස්වයංක්‍රීය ආකාරයේ අනුමාන ගැන හුරුපුරුදු පාඨකයින්, ඇත්ත වශයෙන්ම, මෙම භාෂාවේ විස්තර භාෂාව, උදාහරණයෙන් පවා, වඩාත් හුරුපුරුදු වන අතර, මෙය ප්‍රතිපත්තිමය වශයෙන් නරක නොවන බව පැවසිය හැකිය. මේ සඳහා ඇති විරෝධතා මෙසේය.

  • ඔව්, ඉලක්කය හොඳයි වගේ, නමුත් අහෝ, ඇය සාක්ෂාත් කර නැත
  • රුසියානු විශ්ව විද්‍යාලවල අධ්‍යාපනය තොරතුරු තාක්ෂණ විශේෂතා අතර පවා වෙනස් වේ - සෑම කෙනෙකුම අනුරූප පාඨමාලාව හදාරා නොමැත
  • අවසාන වශයෙන්, අපි දකින පරිදි, ප්රායෝගිකව එය එසේ වේ අවශ්ය නොවේ, විස්තර කර ඇති TL හි පවා සීමිත උප කුලකයක් පමණක් භාවිතා වන බැවින්

කී පරිදි ලියෝනර්ඩ් නාලිකාවේ #perl FreeNode IRC ජාලය තුළ, Telegram සිට Matrix දක්වා ගේට්ටුවක් ක්‍රියාත්මක කිරීමට උත්සාහ කළ (උපුටා දැක්වීමේ පරිවර්තනය මතකයෙන් සාවද්‍ය වේ):

යමෙකු ප්‍රථම වරට න්‍යාය ටයිප් කිරීමට හඳුන්වා දුන් බවක් දැනේ, උද්යෝගිමත් වී, එය ප්‍රායෝගිකව අවශ්‍යද යන්න ගැන සැලකිල්ලක් නොදක්වා එය සමඟ සෙල්ලම් කිරීමට උත්සාහ කළේය.

ප්‍රාථමික දෙයක් ලෙස හිස්-වර්ග (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---, එවිට වාක්‍ය ඛණ්ඩය එලෙසම පවතිනු ඇත, නමුත් අර්ථය වෙනස් වනු ඇත: ඉදිකිරීම්කරු RPC ශ්‍රිතයේ නම බවට පත්වනු ඇත, ක්ෂේත්‍ර පරාමිති බවට පත්වනු ඇත (හොඳයි, එනම්, එය පහත විස්තර කර ඇති පරිදි ලබා දී ඇති ව්‍යුහයම හරියටම පවතිනු ඇත. , මෙය හුදෙක් පවරා ඇති අර්ථය වනු ඇත), සහ "බහුරූපී වර්ගය" - ආපසු ලැබුණු ප්‍රතිඵලයේ වර්ගය. ඇත්ත, එය තවමත් බහුරූපීව පවතිනු ඇත - කොටසේ අර්ථ දක්වා ඇත ---types---, නමුත් මෙම ඉදිකිරීම්කරු "සැලකෙන්නේ නැත". ඔවුන්ගේ තර්ක මගින් හැඳින්වෙන ශ්‍රිත වර්ග අධික ලෙස පැටවීම, i.e. කිසියම් හේතුවක් නිසා, C++ හි මෙන් එකම නම සහිත නමුත් විවිධ අත්සන් සහිත ශ්‍රිත කිහිපයක් TL සඳහා සපයා නැත.

එය OOP නොවේ නම් "ඉදිකිරීම්කරු" සහ "බහුරූපී" ඇයි? හොඳයි, ඇත්ත වශයෙන්ම, යමෙකුට OOP වචන වලින් මේ ගැන සිතීම පහසු වනු ඇත - වියුක්ත පන්තියක් ලෙස බහුරූපී වර්ගයක් වන අතර, ඉදිකිරීම්කරුවන් යනු එහි සෘජු පැවත එන පන්ති, සහ final භාෂා ගණනාවක පාරිභාෂිතය තුළ. ඇත්ත වශයෙන්ම, ඇත්ත වශයෙන්ම, මෙහි පමණි සමානකම OO ක්‍රමලේඛන භාෂා වල සැබෑ අධි බර කන්ස්ට්‍රක්ටර් ක්‍රම සමඟ. මෙහි දත්ත ව්‍යුහයන් පමණක් බැවින්, ක්‍රම කිසිවක් නොමැත (ශ්‍රිත සහ ක්‍රම පිළිබඳ විස්තරය තවදුරටත් ඒවා පවතින බව හිස තුළ ව්‍යාකූලත්වයක් ඇති කිරීමට බෙහෙවින් සමත් වුවද, නමුත් එය වෙනස් කාරණයකි) - ඔබට කන්ස්ට්‍රක්ටරයක් ​​අගයක් ලෙස සිතිය හැකිය. කුමන ඉදිවෙමින් පවතී බයිට් ප්‍රවාහයක් කියවන විට ටයිප් කරන්න.

මෙය සිදු වන්නේ කෙසේද? සෑම විටම බයිට් 4ක් කියවන deserializer අගය දකියි 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>.

සැකිලි සහ ජෙනරික් දෙකම වාසි හෝ ජාවා වල ඇති බව ඔබ සිතනවා විය හැක. නමුත් නැහැ. පාහේ. මෙය එකම තථ්‍ය පරිපථවල කෝණ වරහන් භාවිතා කිරීමේ අවස්ථාව, සහ එය භාවිතා කරන්නේ දෛශිකය සඳහා පමණි. බයිට් ප්‍රවාහයක දී, මේවා දෛශික වර්ගය සඳහාම CRC4 බයිට් 32 ක් වනු ඇත, සෑම විටම සමාන වේ, පසුව බයිට් 4 ක් - අරා මූලද්‍රව්‍ය ගණන, පසුව මෙම මූලද්‍රව්‍ය ම වේ.

අනුක්‍රමිකකරණය සැමවිටම සිදුවන්නේ බයිට් 4 ක වචන වලින් බව මෙයට එක් කරන්න, සියලුම වර්ග එහි ගුණාකාර වේ - ගොඩනඟන ලද වර්ග ද විස්තර කෙරේ. bytes и string දිග ශ්‍රේණිගත කිරීම සහ මෙම පෙළගැස්ම 4 කින් - හොඳයි, එය සාමාන්‍ය සහ සාපේක්ෂ වශයෙන් ඵලදායී බවක් පෙනෙන්නට තිබේද? TL ඵලදායි ද්විමය අනුක්‍රමිකකරණයක් යැයි ප්‍රකාශ කළත්, ඔවුන් සමඟ අපායට, බූලියන් අගයන් සහ තනි අක්ෂර තන්තු පවා බයිට් 4ක් දක්වා ප්‍රසාරණය වීමත් සමඟ, JSON තවමත් වඩා ඝනකයක් වේවිද? බලන්න, අනවශ්‍ය ක්ෂේත්‍ර පවා බිට් ධජ මගින් මඟ හැරිය හැක, සෑම දෙයක්ම ඉතා හොඳයි, සහ අනාගතය සඳහා විස්තීරණය කළ හැකි ය, එබැවින් පසුව ඉදිකිරීම්කරුට නව විකල්ප ක්ෂේත්‍ර එකතු නොකරන්නේ මන්ද?..

නමුත් නැත, ඔබ මගේ කෙටි විස්තරය නොව සම්පූර්ණ ලියකියවිලි කියවා ක්රියාත්මක කිරීම ගැන සිතන්න. පළමුව, ඉදිකිරීම්කරුගේ CRC32 ගණනය කරනු ලබන්නේ යෝජනා ක්‍රමයේ පෙළ විස්තරයේ සාමාන්‍යකරණය කළ රේඛාවට අනුව (අතිරේක සුදු ඉඩ ඉවත් කරන්න, ආදිය) - එබැවින් නව ක්ෂේත්‍රයක් එකතු කළහොත්, වර්ග විස්තර රේඛාව වෙනස් වනු ඇත, එබැවින් එහි CRC32 සහ , ප්රතිඵලයක් වශයෙන්, අනුක්රමිකකරණය. නව ධජ කට්ටලයක් සහිත ක්ෂේත්‍රයක් ඔහුට ලැබුණහොත් සහ ඊළඟට ඒවා සමඟ කුමක් කළ යුතු දැයි ඔහු නොදන්නේ නම් පැරණි සේවාදායකයා කුමක් කරයිද?

දෙවනුව, අපි මතක තබා ගනිමු CRC32, මෙහි අත්‍යවශ්‍යයෙන්ම භාවිතා වන්නේ hash කාර්යයන් අනුක්‍රමික (de)serialized කුමන වර්ගයද යන්න අනන්‍යව තීරණය කිරීමට. මෙහිදී අපි ගැටීම් පිළිබඳ ගැටලුවට මුහුණ දී සිටිමු - සහ නැත, සම්භාවිතාව 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 පමණක් මාරු කරන්නද?

මෙය කිසිසේත්ම නිෂ්ක්‍රීය න්‍යායික ප්‍රශ්නයක් නොවේ - ඔබට කණ්ඩායම් පරිශීලකයින්ගේ ලැයිස්තුවක් ලැබේ යැයි සිතන්න, ඔවුන් එක් එක් හැඳුනුම්පතක්, මුල් නම, අවසාන නම - ජංගම සම්බන්ධතාවයක් හරහා මාරු කළ දත්ත ප්‍රමාණයේ වෙනස සැලකිය යුතු විය හැකිය. එය හරියටම අපට ප්‍රචාරණය කරන්නේ ටෙලිග්‍රාම් මාලාවේ සඵලතාවයයි.

නිසා…

කිසිදා නිකුත් නොකළ දෛශිකය

ඔබ සංයෝජන සහ යනාදී විස්තර පිටු හරහා ගමන් කිරීමට උත්සාහ කරන්නේ නම්, දෛශිකයක් (සහ න්‍යාසයක් පවා) විධිමත් ලෙස පත්‍ර කිහිපයක ටියුපල් හරහා ප්‍රතිදානය කිරීමට උත්සාහ කරන බව ඔබට පෙනෙනු ඇත. නමුත් අවසානයේ දී ඔවුන්ට අමතක වන අතර, අවසාන පියවර මඟ හරින අතර, දෛශිකයක් පිළිබඳ නිර්වචනයක් සරලව ලබා දී ඇත, එය තවමත් වර්ගයකට බැඳී නොමැත. කාරණය කුමක් ද? භාෂාවලින් වැඩසටහන්කරණය, විශේෂයෙන් ක්‍රියාකාරී ඒවා නම්, ව්‍යුහය පුනරාවර්තන ලෙස විස්තර කිරීම සාමාන්‍ය දෙයකි - එහි කම්මැලි ඇගයීම සමඟ සම්පාදකයා සියල්ල තේරුම් ගෙන එයම කරනු ඇත. භාෂාවෙන් දත්ත අනුක්‍රමිකකරණය අවශ්‍ය වන්නේ කාර්යක්ෂමතාවයි: එය සරලව විස්තර කිරීමට ප්‍රමාණවත් වේ ලැයිස්තුව, i.e. මූලද්‍රව්‍ය දෙකක ව්‍යුහය - පළමුවැන්න දත්ත මූලද්‍රව්‍යයකි, දෙවැන්න එකම ව්‍යුහය හෝ වලිගය සඳහා හිස් ඉඩකි (පැක් (cons) Lisp හි). නමුත් මෙය පැහැදිලිවම අවශ්ය වනු ඇත එකිනෙකා මූලද්‍රව්‍ය එහි වර්ගය විස්තර කිරීමට අමතර බයිට් 4ක් (TL හි ඇති අවස්ථාවක CRC32) වැය කරයි. අරාවක් ද පහසුවෙන් විස්තර කළ හැකිය ස්ථාවර ප්රමාණය, නමුත් කල්තියා නොදන්නා දිග අරාවක අවස්ථාවක, අපි බිඳී.

එබැවින්, TL දෛශිකයක් ප්‍රතිදානය කිරීමට ඉඩ නොදෙන බැවින්, එය පැත්තකින් එකතු කිරීමට සිදු විය. අවසානයේ ලියකියවිලි මෙසේ කියයි:

අනුක්‍රමිකකරණය සෑම විටම t වර්ගයේ විචල්‍යයේ නිශ්චිත අගය මත රඳා නොපවතින එකම නිර්මාපක “දෛශිකය” (const 0x1cb5c415 = crc32(“දෛශික t: වර්ගය # [ t ] = Vector t”) භාවිතා කරයි.

විකල්ප පරාමිතිය t හි අගය එය ප්‍රතිඵල වර්ගයෙන් ව්‍යුත්පන්න වී ඇති බැවින් අනුක්‍රමිකකරණයට සම්බන්ධ නොවේ (සෑම විටම deserialization කිරීමට පෙර දන්නා).

සමීපව බලන්න: vector {t:Type} # [ t ] = Vector t - ඒත් කොතැනකවත් නැත පළමු අංකය දෛශිකයේ දිගට සමාන විය යුතු බව මෙම නිර්වචනයම නොකියයි! ඒ වගේම කොහෙන්වත් එන්නේ නැහැ. මෙය ඔබේ දෑතින් මතක තබාගෙන ක්‍රියාත්මක කළ යුතු දීමනාවකි. වෙනත් තැන්වල, ලේඛනය පවා අවංකව සඳහන් කරන්නේ වර්ගය සැබෑ නොවන බවයි:

දෛශික t බහුරූපී ව්‍යාජ මාදිලිය යනු "වර්ගය" වන අතර එහි අගය කොටු හෝ හිස් ඕනෑම වර්ගයක අගයන් අනුපිළිවෙලකි.

... නමුත් ඒ ගැන අවධානය යොමු කරන්නේ නැහැ. ගණිතය දිගහැරීමෙන් වෙහෙසට පත්ව සිටින ඔබ (සමහරවිට ඔබ විශ්ව විද්‍යාල පාඨමාලාවකින් පවා දන්නා) එය අත්හැරීමට තීරණය කර ප්‍රායෝගිකව එය සමඟ වැඩ කරන්නේ කෙසේදැයි සොයා බලන විට, ඔබේ හිසෙහි ඉතිරි වන හැඟීම නම් මෙය බරපතල බවයි. මූලික වශයෙන් ගණිතය, එය පැහැදිලිවම නිර්මාණය කරන ලද්දේ Cool People (ගණිතඥයින් දෙදෙනෙකු - ACM ජයග්‍රාහකයා) විසින් මිස කිසිවෙකු නොවේ. ඉලක්කය - පෙන්වීමට - සාක්ෂාත් කර ඇත.

මාර්ගය වන විට, අංකය ගැන. අපි එය ඔබට මතක් කරමු # එය සමාන පදයකි nat, ස්වභාවික අංකය:

වර්ග ප්‍රකාශන ඇත (type-expr) සහ සංඛ්‍යාත්මක ප්‍රකාශන (nat-expr) කෙසේ වෙතත්, ඒවා එකම ආකාරයකින් අර්ථ දක්වා ඇත.

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

නමුත් ව්යාකරණ තුළ ඔවුන් විස්තර කර ඇත්තේ එකම ආකාරයෙන්, i.e. මෙම වෙනස නැවත මතක තබා ගත යුතු අතර අතින් ක්‍රියාත්මක කළ යුතුය.

හොඳයි, ඔව්, අච්චු වර්ග (vector<int>, vector<User>) පොදු හඳුනාගැනීමක් ඇත (#1cb5c415), i.e. ඇමතුම ලෙස නිවේදනය කරන බව ඔබ දන්නේ නම්

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

එවිට ඔබ තවදුරටත් බලා සිටින්නේ දෛශිකයක් පමණක් නොව, පරිශීලකයන්ගේ දෛශිකයක් පමණි. වඩාත් නිවැරදිව, විය යුතු ය රැඳී සිටින්න - සැබෑ කේතය තුළ, සෑම මූලද්‍රව්‍යයක්ම, හිස් වර්ගයක් නොවේ නම්, ඉදිකිරීම්කරුවෙකු සිටින අතර, ක්‍රියාත්මක කිරීමේදී හොඳ ආකාරයකින් එය පරීක්ෂා කිරීමට අවශ්‍ය වනු ඇත - නමුත් මෙම දෛශිකයේ සෑම මූලද්‍රව්‍යයක්ම අපව යවා ඇත එම වර්ගය? එය යම් ආකාරයක PHP නම්, අරාවක විවිධ මූලද්‍රව්‍යවල විවිධ වර්ග අඩංගු විය හැකි නම් කුමක් කළ යුතුද?

මෙම අවස්ථාවේදී ඔබ සිතන්නට පටන් ගනී - එවැනි TL අවශ්යද? සමහර විට කරත්තය සඳහා මිනිස් ශ්‍රේණිගත කිරීමක් භාවිතා කළ හැකිද, ඒ වන විටත් පැවති එම ප්‍රොටෝබුෆ්? ඒක තමයි න්‍යාය, අපි බලමු ප්‍රායෝගිකව.

කේතය තුළ පවතින TL ක්‍රියාත්මක කිරීම්

ඩුරොව්ගේ කොටස විකිණීමත් සමඟ සුප්‍රසිද්ධ සිදුවීම් වලට පෙර සිටම TL උපත ලැබුවේ VKontakte හි ගැඹුරේය.නියත වශයෙන්ම), ටෙලිග්‍රාම් සංවර්ධනය ආරම්භ වීමටත් පෙර. සහ විවෘත මූලාශ්‍රවල පළමු ක්රියාත්මක කිරීමේ මූල කේතය ඔබට විහිලු අත්වාරු රාශියක් සොයාගත හැකිය. දැන් ටෙලිග්‍රාම් හි පවතිනවාට වඩා භාෂාවම එහි ක්‍රියාත්මක විය. උදාහරණයක් ලෙස, යෝජනා ක්‍රමයේ හෑෂ් කිසිසේත්ම භාවිතා නොවේ (එනම් අපගමන හැසිරීම් සහිත බිල්ට්-ඉන් ව්‍යාජ මාදිලියක් (දෛශිකයක් වැනි) යන්නයි. හෝ

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 යුගල වල දෛශිකයක් ලෙස හැෂ්මැප් අච්චු වර්ගයක අර්ථ දැක්වීම මෙයයි. C++ හි එය මේ වගේ දෙයක් පෙනෙනු ඇත:

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

ඒ නිසා, alpha - මූල පදය! නමුත් C++ හි පමණක් ඔබට T ලිවිය හැකිය, නමුත් ඔබ ඇල්ෆා, බීටා ලිවිය යුතුය ... නමුත් පරාමිති 8 කට වඩා වැඩි නොවේ, මනඃකල්පිතය අවසන් වන්නේ එයයි. වරක් ශාන්ත පීටර්ස්බර්ග්හි මෙවැනි දෙබස් කිහිපයක් සිදු වූ බව පෙනේ:

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

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

නමුත් මෙය "පොදුවේ" TL හි පළමු ප්‍රකාශිත ක්‍රියාත්මක කිරීම ගැන විය. ටෙලිග්‍රාම් සේවාදායකයින් තුළම ක්‍රියාත්මක කිරීම් සලකා බැලීමට අපි ඉදිරියට යමු.

Vasily වෙත වචනය:

Vasily, [09.10.18 17:07] සියල්ලටම වඩා, බූරුවා උණුසුම් වන්නේ ඔවුන් වියුක්තයන් රාශියක් නිර්මාණය කර, පසුව ඒවා මත බෝල්ට් එකක් ගසා, කේත උත්පාදක යන්ත්‍රය කිහිලිකරුවලින් ආවරණය කළ බැවිනි.
ප්‍රතිඵලයක් වශයෙන්, පළමුව dock pilot.jpg වෙතින්
ඉන්පසු dzhekichan.webp කේතයෙන්

ඇත්ත වශයෙන්ම, ඇල්ගොරිතම සහ ගණිතය ගැන හුරුපුරුදු පුද්ගලයින්ගෙන්, ඔවුන් Aho, Ullmann කියවා ඇති බවත්, දශක ගණනාවක් තිස්සේ ඔවුන්ගේ DSL සම්පාදක ලිවීම සඳහා කර්මාන්තයේ තථ්‍ය ප්‍රමිතියක් බවට පත්ව ඇති මෙවලම් පිළිබඳව හුරුපුරුදු බවත් අපට අපේක්ෂා කළ හැකිය, නේද?

විසින් ටෙලිග්‍රාම්-ක්ලි Vitaly Valtman යනු, TLO ආකෘතිය එහි (cli) සීමාවෙන් පිටත සිදුවීමෙන් තේරුම් ගත හැකි පරිදි, කණ්ඩායමේ සාමාජිකයෙකි - දැන් TL විග්‍රහ කිරීම සඳහා පුස්තකාලයක් වෙන් කර ඇත. වෙනම, ඇයගේ හැඟීම කුමක්ද? TL විග්‍රහකය? ..

16.12 04:18 Vasily: මම හිතන්නේ කවුරුහරි lex+yacc ප්‍රගුණ කළේ නැහැ
16.12 04:18 Vasily: මට එය වෙනත් ආකාරයකින් පැහැදිලි කළ නොහැක
16.12 04:18 Vasily: හොඳයි, නැත්නම් VK හි පේළි ගණන සඳහා ඔවුන්ට ගෙවන ලදී
16.12 04:19 Vasily: 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 වර්ග සඳහා ව්‍යතිරේක ලැයිස්තුවක් ඇත. නොගැලපේ රූප සටහනේ දක්වා ඇති එකක් සමඟ!

Vasily, [18.12/22 49:XNUMX] සහ මෙන්න මම හිතන්නේ එවැනි TL එකක් අවශ්‍යද යන්න ගැන
මට විකල්ප ක්‍රියාත්මක කිරීම් සමඟ අවුල් කිරීමට අවශ්‍ය නම්, මම රේඛා බිඳීම් ඇතුළු කිරීමට පටන් ගනිමි, විග්‍රහ කරන්නන්ගෙන් අඩක් බහු-රේඛා අර්ථ දැක්වීම් මත බිඳී යනු ඇත
කෙසේ වෙතත්, tdesktop ද

එක්-ලයිනර් පිළිබඳ කාරණය මතක තබා ගන්න, අපි ටික වේලාවකට පසුව එය වෙත ආපසු යන්නෙමු.

හරි, telegram-cli නිල නොවන, Telegram Desktop නිල, නමුත් අනෙක් ඒවා ගැන කුමක් කිව හැකිද? කවුද දන්නේ?.. ඇන්ඩ්‍රොයිඩ් ග්‍රාහක කේතයේ ස්කීමා විග්‍රහයක් තිබුණේ නැත (එය විවෘත මූලාශ්‍ර පිළිබඳ ප්‍රශ්න මතු කරයි, නමුත් මෙය දෙවන කොටස සඳහා ය), නමුත් තවත් විහිලු කේත කිහිපයක් තිබුණි, නමුත් ඒවා පිළිබඳ වැඩි විස්තර පහත උපවගන්තිය.

අනුක්‍රමිකකරණය ප්‍රායෝගිකව මතු කරන වෙනත් ප්‍රශ්න මොනවාද? උදාහරණයක් ලෙස, ඔවුන් බොහෝ දේ කළා, ඇත්ත වශයෙන්ම, බිට් ක්ෂේත්‍ර සහ කොන්දේසි සහිත ක්ෂේත්‍ර සමඟ:

Vasily: flags.0? true
ධජය සකසා ඇත්නම් ක්ෂේත්‍රය පවතින අතර සත්‍යයට සමාන වේ

Vasily: flags.1? int
යන්නෙන් අදහස් වන්නේ ක්ෂේත්‍රය පවතින අතර එය ඉවත් කළ යුතු බවයි

Vasily: බූරුවා, ඔබ කරන දේ ගැන කරදර නොවන්න!
Vasily: සත්‍ය යනු හිස් ශුන්‍ය දිග වර්ගයක් බව ලේඛනයේ කොතැනක හෝ සඳහනක් ඇත, නමුත් ඔවුන්ගේ ලේඛනයෙන් කිසිවක් එකලස් කළ නොහැක
Vasily: විවෘත මූලාශ්‍ර ක්‍රියාත්මක කිරීමේදී මෙය එසේ නොවේ, නමුත් කිහිලිකරු සහ ආධාරක පොකුරක් ඇත

Telethon ගැන කුමක් කිව හැකිද? MTProto හි මාතෘකාව දෙස බලා සිටීම, උදාහරණයක් - ලේඛනවල එවැනි කෑලි ඇත, නමුත් ලකුණ % එය විස්තර කර ඇත්තේ "දී ඇති හිස්-වර්ගයට අනුරූප" ලෙස පමණි, i.e. පහත උදාහරණ වල දෝෂයක් හෝ ලේඛනගත නොකළ දෙයක් ඇත:

Vasily, [22.06.18 18:38] එක තැනක:

msg_container#73f1f8dc messages:vector message = MessageContainer;

වෙනස් ආකාරයකින්:

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

ඒවගේම මේවා ලොකු වෙනස්කම් දෙකක්, සැබෑ ජීවිතයේදී යම් ආකාරයක නිරුවත් දෛශිකයක් එනවා

මම හිස් දෛශික නිර්වචනයක් දැක නැති අතර එකක් හමු වී නැත

විශ්ලේෂණය ටෙලිතන් අතින් ලියැවී ඇත

ඔහුගේ රූප සටහනේ නිර්වචනය අදහස් දක්වා ඇත msg_container

නැවතත්, ප්‍රශ්නය % පමණ වේ. එය විස්තර කර නැත.

Vadim Goncharov, [22.06.18 19:22] සහ tdesktop එකේද?

Vasily, [22.06.18 19:23] නමුත් සාමාන්‍ය එන්ජින්වල ඇති ඔවුන්ගේ TL විග්‍රහකය බොහෝ විට මෙය අනුභව නොකරනු ඇත.

// parsed manually

TL යනු ලස්සන වියුක්තයකි, කිසිවෙකු එය සම්පූර්ණයෙන්ම ක්රියාත්මක නොකරයි

සහ % ඔවුන්ගේ යෝජනා ක්‍රමයේ අනුවාදයේ නොමැත

නමුත් මෙහි ලේඛනගත කිරීම පරස්පර වේ, එබැවින් idk

එය ව්‍යාකරණ වලින් හමු විය, ඔවුන්ට හුදෙක් අර්ථ ශාස්ත්‍රය විස්තර කිරීමට අමතක විය හැකිය

ඔබ TL හි ලේඛනය දුටුවා, ඔබට ලීටර් භාගයක් නොමැතිව එය හඳුනාගත නොහැක

"හොඳයි, අපි කියමු" තවත් පාඨකයෙකු පවසනු ඇත, "ඔබ යමක් විවේචනය කරයි, එබැවින් එය කළ යුතු ආකාරය මට පෙන්වන්න."

Vasily පිළිතුරු දෙයි: “විග්‍රහ කරන්නා සම්බන්ධයෙන් ගත් කල, මම එවැනි දේවලට කැමතියි

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

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

කෙසේ හෝ එයට වඩා හොඳයි

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

හෝ

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

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

මෙය සමස්ත ලෙක්සර් ය:

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

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

එම. වඩා සරල වන්නේ එය මෘදු ලෙස තැබීමයි."

සාමාන්‍යයෙන්, ප්‍රතිඵලයක් ලෙස, TL හි සත්‍ය වශයෙන්ම භාවිතා කරන ලද උප කුලකයේ විග්‍රහකය සහ කේත උත්පාදක යන්ත්‍රය ආසන්න වශයෙන් ව්‍යාකරණ පේළි 100කට සහ ජනකයේ පේළි ~300කට ගැලපේ (සියල්ල ගණන් කරමින් printගේ උත්පාදනය කරන ලද කේතය), එක් එක් පන්තියේ අභ්‍යන්තර පරීක්‍ෂණය සඳහා ටයිප් තොරතුරු බනිස් ඇතුළුව. සෑම බහුරූපී වර්ගයක්ම හිස් වියුක්ත පාදක පන්තියක් බවට පත් වන අතර, ඉදිකිරීම්කරුවන්ට එයින් උරුම වන අතර අනුක්‍රමිකකරණය සහ ඩීරියල්කරණය සඳහා ක්‍රම තිබේ.

ටයිප් භාෂාවේ වර්ග නොමැතිකම

ශක්තිමත් ටයිප් කිරීම හොඳ දෙයක් නේද? නැත, මෙය හොලිවර් එකක් නොවේ (මම ගතික භාෂා වලට කැමති වුවද), නමුත් TL රාමුව තුළ උපකල්පනයකි. එය මත පදනම්ව, භාෂාව අපට සියලු ආකාරයේ චෙක්පත් සැපයිය යුතුය. හොඳයි, හරි, සමහර විට ඔහුම නොවේ, නමුත් ක්රියාත්මක කිරීම, නමුත් ඔහු අවම වශයෙන් ඒවා විස්තර කළ යුතුය. සහ අපට අවශ්‍ය කුමන ආකාරයේ අවස්ථාද?

පළමුවෙන්ම, සීමාවන්. ගොනු උඩුගත කිරීම සඳහා වන ලේඛනවල අපි බලමු:

ගොනුවේ ද්විමය අන්තර්ගතය පසුව කොටස් වලට බෙදා ඇත. සියලුම කොටස් එකම ප්‍රමාණයෙන් තිබිය යුතුය ( කොටස_ප්‍රමාණය ) සහ පහත කොන්දේසි සපුරාලිය යුතුය:

  • part_size % 1024 = 0 (1KB කින් බෙදිය හැකිය)
  • 524288 % part_size = 0 (512KB කොටස්_ප්‍රමාණයෙන් ඒකාකාරව බෙදිය යුතුය)

එහි විශාලත්වය part_size ට වඩා අඩු නම්, අවසාන කොටස මෙම කොන්දේසි සපුරාලිය යුතු නැත.

සෑම කොටසකටම අනුක්‍රමික අංකයක් තිබිය යුතුය, ගොනු_කොටස, 0 සිට 2,999 දක්වා පරාසයක අගයක් සහිතව.

ගොනුව කොටස් කළ පසු, ඔබ එය සේවාදායකයේ සුරැකීමට ක්රමයක් තෝරාගත යුතුය. භාවිත upload.saveBigFilePart ගොනුවේ සම්පූර්ණ ප්‍රමාණය 10 MB ට වඩා වැඩි නම් සහ upload.saveFilePart කුඩා ගොනු සඳහා.
[…] පහත දත්ත ආදාන දෝෂ වලින් එකක් ආපසු ලබා දිය හැක:

  • FILE_PARTS_INVALID — වලංගු නොවන කොටස් ගණන. අගය අතර නොවේ 1..3000

මේ කිසිවක් රූප සටහනේ තිබේද? මෙය කෙසේ හෝ TL භාවිතයෙන් ප්‍රකාශ කළ හැකිද? නැත. නමුත් සමාවෙන්න, සීයාගේ Turbo Pascal පවා නිශ්චිත වර්ග විස්තර කිරීමට සමත් විය පරාසයන්. ඔහු තවත් එක් දෙයක් දැන සිටියේය, දැන් එය වඩාත් හොඳින් හැඳින්වේ enum - ස්ථාවර (කුඩා) අගයන් ගණනක ගණනය කිරීමකින් සමන්විත වර්ගයකි. C - numeric වැනි භාෂාවලින්, අපි මෙතෙක් කතා කර ඇත්තේ වර්ග ගැන පමණක් බව සලකන්න අංක. හැබැයි arrays, strings එහෙමත් තියෙනවා... උදාහරණයක් විදියට මේ string එකේ තියෙන්න පුළුවන් phone number එකක් විතරයි කියලා විස්තර කළොත් හොඳයි නේද?

මේ එකක්වත් TL එකේ නැහැ. නමුත් උදාහරණයක් ලෙස, JSON Schema හි ඇත. 512 KB බෙදීම ගැන වෙනත් කෙනෙකුට තර්ක කළ හැකි නම්, මෙය තවමත් කේතයෙන් පරීක්ෂා කළ යුතු බව, එවිට සේවාදායකයා සරලව තහවුරු කර ගන්න මට බැරි වුණා පරාසයෙන් පිටත අංකයක් යවන්න 1..3000 (සහ අනුරූප දෝෂය ඇති විය නොහැක) එය කළ හැකි වනු ඇත, හරිද?..

මාර්ගය වන විට, දෝෂ සහ ආපසු අගයන් ගැන. TL සමඟ වැඩ කර ඇති අය පවා ඔවුන්ගේ ඇස් බොඳ කරයි - එය අපට වහාම වැටහුණේ නැත හැම එකම TL හි ශ්‍රිතයකට ඇත්ත වශයෙන්ම විස්තර කර ඇති ප්‍රතිලාභ වර්ගය පමණක් නොව දෝෂයක් ද ලබා දිය හැක. නමුත් මෙය TL භාවිතා කර කිසිම ආකාරයකින් නිගමනය කළ නොහැක. ඇත්ත වශයෙන්ම, එය දැනටමත් පැහැදිලි වන අතර ප්‍රායෝගිකව කිසිවක් අවශ්‍ය නොවේ (ඇත්ත වශයෙන්ම, RPC විවිධ ආකාරවලින් කළ හැකි වුවද, අපි මෙය පසුවට පැමිණෙමු) - නමුත් වියුක්ත වර්ගවල ගණිතයේ සංකල්පවල සංශුද්ධතාවය ගැන කුමක් කිව හැකිද? දිව්‍ය ලෝකයෙන්?

අවසාන වශයෙන්, කියවීමේ හැකියාව ගැන කුමක් කිව හැකිද? හොඳයි, එහිදී, පොදුවේ, මම කැමතියි විස්තර එය ක්‍රමලේඛනයේ නිවැරදිව තිබේද (JSON යෝජනා ක්‍රමයේ, නැවතත්, එයයි), නමුත් ඔබ දැනටමත් එය සමඟ වෙහෙසට පත්ව සිටී නම්, ප්‍රායෝගික පැත්ත ගැන කුමක් කිව හැකිද - අවම වශයෙන් යාවත්කාලීන කිරීමේදී වෙනස්කම් දෙස සුළු වශයෙන් බැලීම? දී ඔබම බලන්න සැබෑ උදාහරණ:

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

හෝ

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

එය සෑම කෙනෙකුම මත රඳා පවතී, නමුත් GitHub, උදාහරණයක් ලෙස, එවැනි දිගු රේඛා ඇතුළත වෙනස්කම් ඉස්මතු කිරීම ප්රතික්ෂේප කරයි. ක්‍රීඩාව “වෙනස්කම් 10ක් සොයා ගන්න”, සහ මොළය වහාම දකින දෙය නම් උදාහරණ දෙකෙහිම ආරම්භය සහ අවසානය එක හා සමානයි, ඔබ වෙහෙසකර ලෙස මැද කොතැනක හෝ කියවිය යුතුය ... මගේ මතය අනුව, මෙය න්‍යායේ පමණක් නොවේ, නමුත් සම්පූර්ණයෙන්ම දෘශ්යමය වශයෙන් අපිරිසිදු හා අලස.

මාර්ගය වන විට, න්යායේ සංශුද්ධතාවය ගැන. අපට බිට් ක්ෂේත්‍ර අවශ්‍ය වන්නේ ඇයි? පෙනෙන්නේ නැද්ද ඔවුන් සුවඳ වර්ගයේ සිද්ධාන්තයේ දෘෂ්ටි කෝණයෙන් නරකද? පැහැදිලි කිරීම රූප සටහනේ පෙර අනුවාදවල දැකිය හැකිය. මුලදී, ඔව්, එය එසේ විය, සෑම කිවිසුම් යාමක් සඳහාම නව වර්ගයක් නිර්මාණය විය. මෙම මූලයන් තවමත් මෙම ස්වරූපයෙන් පවතී, උදාහරණයක් ලෙස:

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

නමුත් දැන් සිතන්න, ඔබේ ව්‍යුහයේ විකල්ප ක්ෂේත්‍ර 5ක් තිබේ නම්, ඔබට හැකි විකල්ප සඳහා වර්ග 32ක් අවශ්‍ය වේ. සංයුක්ත පිපිරීම. මේ අනුව, අනුක්‍රමිකකරණයේ කටුක යථාර්ථයේ වාත්තු-යකඩ බූරුවාට එරෙහිව TL න්‍යායේ ස්ඵටික සංශුද්ධතාවය නැවත වරක් බිඳ වැටුණි.

ඊට අමතරව, සමහර ස්ථානවල මෙම පුද්ගලයින් විසින්ම ඔවුන්ගේම යතුරු ලියනය උල්ලංඝනය කරයි. උදාහරණයක් ලෙස, MTProto (ඊළඟ පරිච්ඡේදය) හි ප්රතිචාරය Gzip මගින් සම්පීඩනය කළ හැක, සියල්ල හොඳයි - ස්ථර සහ පරිපථය උල්ලංඝනය වීම හැර. නැවත වරක්, නෙලා ගත්තේ RpcResult නොව එහි අන්තර්ගතයයි. හොඳයි, ඇයි මෙහෙම කරන්නේ?

හෝ තවත් උදාහරණයක්, අපි වරක් දෝෂයක් සොයා ගත්තා - එය යවා ඇත InputPeerUser වෙනුවට InputUser. නැතහොත් අනෙක් අතට. නමුත් එය වැඩ කළා! එනම්, සේවාදායකයා වර්ගය ගැන තැකීමක් නොකළේය. මෙය කෙසේ විය හැකිද? Telegram-cli වෙතින් කේත කොටස් මගින් පිළිතුර අපට ලබා දිය හැකිය:

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

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

වෙනත් වචන වලින් කිවහොත්, ශ්‍රේණිගත කිරීම සිදු කරනු ලබන්නේ මෙහිදීය අතින්, උත්පාදනය නොකළ කේතය! සමහරවිට සේවාදායකය සමාන ආකාරයකින් ක්රියාත්මක කර තිබේද?.. ප්රතිපත්තිමය වශයෙන්, මෙය එක් වරක් සිදු කළහොත් ක්රියා කරනු ඇත, නමුත් යාවත්කාලීන කිරීමේදී එය පසුව සහාය වන්නේ කෙසේද? මෙම යෝජනා ක්රමය සොයා ගත්තේ මේ නිසාද? මෙන්න අපි ඊළඟ ප්‍රශ්නයට යමු.

අනුවාදනය කිරීම. ස්ථර

ක්‍රමානුරූප අනුවාද ස්ථර ලෙස හඳුන්වන්නේ ඇයිද යන්න අනුමාන කළ හැක්කේ ප්‍රකාශිත ක්‍රමලේඛන ඉතිහාසය මත පදනම්ව පමණි. පෙනෙන විදිහට, මුලදී කතුවරුන් සිතුවේ නොවෙනස් වූ යෝජනා ක්‍රමය භාවිතයෙන් මූලික දේවල් කළ හැකි බවත්, අවශ්‍ය අවස්ථාවලදී පමණක්, විශේෂිත ඉල්ලීම් සඳහා, ඒවා වෙනත් අනුවාදයක් භාවිතයෙන් සිදු කරන බවත්ය. ප්‍රතිපත්තිමය වශයෙන්, හොඳ අදහසක් පවා - සහ අලුත් දේ පැරණි දේට ඉහළින් “මිශ්‍ර” වනු ඇත. නමුත් එය සිදු කළේ කෙසේදැයි බලමු. ඇත්ත, මට මුල සිටම එය දෙස බැලීමට නොහැකි විය - එය විහිළුවක්, නමුත් මූලික ස්ථරයේ රූප සටහන සරලව නොපවතී. ස්ථර 2 න් ආරම්භ විය. ලේඛන විශේෂ TL විශේෂාංගයක් ගැන අපට කියයි:

සේවාලාභියෙකු 2 වන ස්ථරයට සහය දක්වන්නේ නම්, පහත ඉදිකිරීම්කරු භාවිතා කළ යුතුය:

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

ප්‍රායෝගිකව, මෙයින් අදහස් කරන්නේ සෑම API ඇමතුමකටම පෙර, අගය සහිත int එකක් බවයි 0x289dd1f6 ක්රම අංකයට පෙර එකතු කළ යුතුය.

සාමාන්ය ශබ්ද. නමුත් ඊළඟට සිදු වූයේ කුමක්ද? පසුව පෙනී සිටියේය

invokeWithLayer3#b7475268 query:!X = X;

ඉතින් ඊළඟට කුමක් ද? ඔබ අනුමාන කළ හැකි පරිදි,

invokeWithLayer4#dea0d430 query:!X = X;

විහිළුවක්ද? නැහැ, හිනා වෙන්න කල් වැඩියි, ඒක ගැන හිතන්න සෑම එකක්ම වෙනත් ස්ථරයකින් ඉල්ලීමක් එවැනි විශේෂ වර්ගයකින් ඔතා තිබිය යුතුය - ඒවා සියල්ලම ඔබට වෙනස් නම්, ඔබට ඒවා වෙන්කර හඳුනාගත හැක්කේ කෙසේද? ඉදිරියෙන් බයිට් 4 ක් එකතු කිරීම ඉතා කාර්යක්ෂම ක්‍රමයකි. ඒ නිසා,

invokeWithLayer5#417a57ae query:!X = X;

නමුත් ටික කලක් යන විට මෙය යම් ආකාරයක බචානාලියාවක් බවට පත්වන බව නම් පැහැදිලිය. සහ විසඳුම පැමිණියේ:

යාවත්කාලීන කිරීම: 9 වන ස්ථරයෙන් පටන් ගෙන, උපකාරක ක්‍රම invokeWithLayerN සමඟ පමණක් භාවිතා කළ හැකිය initConnection

හුරේ! අනුවාද 9 කට පසු, අපි අවසානයේ 80 ගණන්වල අන්තර්ජාල ප්‍රොටෝකෝලවල සිදු කළ දේ වෙත පැමිණියෙමු - සම්බන්ධතාවයේ ආරම්භයේදීම අනුවාදයට එකඟ වීම!

ඉතින් ඊළඟට කුමක් ද? ..

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

ඒත් දැන් ඔයාට හිනා වෙන්න පුළුවන්. තවත් ස්ථර 9 කට පසුව පමණක්, අනුවාද අංකයක් සහිත විශ්වීය ඉදිකිරීම්කරුවෙකු අවසානයේ එකතු කරන ලදී, එය සම්බන්ධතාවයේ ආරම්භයේදී එක් වරක් පමණක් ඇමතීමට අවශ්‍ය වන අතර, ස්ථර වල අර්ථය අතුරුදහන් වී ඇති බවක් පෙනෙන්නට තිබුණි, දැන් එය කොන්දේසි සහිත අනුවාදයක් පමණි. අනෙක් සෑම තැනකම. ගැටලුව විසඳා ඇත.

හරියටම? ..

Vasily, [16.07.18 14:01] සිකුරාදා පවා මම හිතුවා:
ටෙලිසර්වර් ඉල්ලීමකින් තොරව සිදුවීම් යවයි. ඉල්ලීම් InvokeWithLayer හි ඔතා තිබිය යුතුය. සේවාදායකය යාවත්කාලීන කිරීම් ආවරණය නොකරයි; ප්‍රතිචාර සහ යාවත්කාලීන කිරීම් එතීමට ව්‍යුහයක් නොමැත.

එම. සේවාලාභියාට යාවත්කාලීන කිරීමට අවශ්‍ය ස්ථරය සඳහන් කළ නොහැක

Vadim Goncharov, [16.07.18 14:02] InvokeWithLayer ප්‍රතිපත්තිමය වශයෙන් කිහිලිකරුවක් නොවේද?

Vasily, [16.07.18 14:02] එකම මාර්ගය මෙයයි

Vadim Goncharov, [16.07.18 14:02] මින් අදහස් විය යුත්තේ සැසියේ ආරම්භයේ දී ස්ථරයට එකඟ වීම ය.

මාර්ගය වන විට, සේවාලාභියා පහත හෙලීම සපයා නොමැති බව අනුගමනය කරයි

යාවත්කාලීන, 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 හි යමක් හඳුනා නොගන්නේ නම්, එය අත්සනින් ද්විමය වේ, තව දුරටත් පහළට සෑම යනවා, විකේතනය කළ නොහැකි වනු ඇත. එවැනි තත්වයක් තුළ ඔබ කළ යුත්තේ කුමක්ද?

හොඳයි, ඕනෑම කෙනෙකුගේ මතකයට එන පළමු දෙය නම් විසන්ධි කර නැවත උත්සාහ කිරීමයි. උදව් කළේ නැහැ. අපි google CRC32 - අපි 73 මත වැඩ කළද, මේවා යෝජනා ක්‍රමය 82 වෙතින් වස්තූන් බවට පත් විය. අපි ලඝු-සටහන් දෙස හොඳින් බලන්නෙමු - විවිධ යෝජනා ක්‍රම දෙකකින් හඳුනාගැනීම් තිබේ!

සමහර විට ගැටලුව සම්පූර්ණයෙන්ම අපගේ නිල නොවන සේවාදායකයා තුළ තිබේද? නැත, අපි ටෙලිග්‍රාම් ඩෙස්ක්ටොප් 1.2.17 දියත් කරන්නෙමු (ලිනක්ස් බෙදාහැරීම් ගණනාවකින් අනුවාදය සපයනු ලැබේ), එය ව්‍යතිරේක ලොගයට ලියයි: MTP අනපේක්ෂිත ආකාරයේ id #b5223b0f MTPMessageMedia හි කියවා ඇත…

ටෙලිග්‍රාම් හි ප්‍රොටෝකෝලය සහ සංවිධානාත්මක ප්‍රවේශයන් විවේචනය කිරීම. 1 කොටස, තාක්ෂණික: මුල සිටම සේවාදායකයකු ලිවීමේ අත්දැකීම - TL, MT

ගූගල් විසින් නිල නොවන සේවාදායකයෙකුට දැනටමත් සමාන ගැටළුවක් ඇති බව පෙන්වූ නමුත් පසුව අනුවාද අංක සහ ඒ අනුව උපකල්පන වෙනස් විය ...

එසේනම් අප කළ යුත්තේ කුමක්ද? Vasily සහ මම වෙන් විය: ඔහු පරිපථය 91 දක්වා යාවත්කාලීන කිරීමට උත්සාහ කළේය, මම දින කිහිපයක් බලා සිට 73 උත්සාහ කිරීමට තීරණය කළෙමි. මෙම ක්‍රම දෙකම ක්‍රියාත්මක විය, නමුත් ඒවා ආනුභවික බැවින්, ඔබට කොපමණ අනුවාද ඉහළට හෝ පහළට අවශ්‍යද යන්න පිළිබඳ අවබෝධයක් නොමැත. පැනීමට, හෝ ඔබ කොපමණ කාලයක් බලා සිටිය යුතුද .

පසුව මට තත්වය ප්‍රතිනිෂ්පාදනය කිරීමට හැකි විය: අපි සේවාදායකයා දියත් කරන්න, එය ක්‍රියා විරහිත කරන්න, පරිපථය වෙනත් ස්ථරයකට නැවත සම්පාදනය කරන්න, නැවත ආරම්භ කරන්න, ගැටලුව නැවත අල්ලා ගන්න, පෙර එකට ආපසු යන්න - අපොයි, පරිපථ මාරු කිරීමක් නොමැති අතර සේවාදායකයා නැවත ආරම්භ කරයි. මිනිත්තු කිහිපයක් උපකාරී වනු ඇත. ඔබට විවිධ ස්ථර වලින් දත්ත ව්‍යුහයන් මිශ්‍රණයක් ලැබෙනු ඇත.

පැහැදිලි කිරීමක්? විවිධ වක්‍ර රෝග ලක්ෂණ වලින් ඔබට අනුමාන කළ හැකි පරිදි, සේවාදායකය විවිධ යන්ත්‍රවල විවිධ ක්‍රියාවලීන්ගෙන් සමන්විත වේ. බොහෝ දුරට ඉඩ, "බෆරින්" සඳහා වගකිව යුතු සේවාදායකයා එහි ඉහළ නිලධාරීන් විසින් ලබා දුන් දේ පෝලිමේ තබා ඇති අතර, ඔවුන් එය උත්පාදනය කරන අවස්ථාවේ දී තිබූ යෝජනා ක්රමයට ලබා දී ඇත. මෙම පෝලිම "දිරාපත්" වන තුරු, ඒ ගැන කිසිවක් කළ නොහැකි විය.

සමහර විට ... නමුත් මෙය දරුණු කිහිලිකරුවෙක්ද?!.. නැහැ, පිස්සු අදහස් ගැන සිතීමට පෙර, නිල සේවාදායකයින්ගේ කේතය දෙස බලමු. ඇන්ඩ්‍රොයිඩ් අනුවාදයේ අපට කිසිදු TL විග්‍රහයක් හමු නොවේ, නමුත් අපට (de)serialization සමඟ අධික ගොනුවක් (GitHub එය ස්පර්ශ කිරීම ප්‍රතික්ෂේප කරයි) සොයා ගනී. මෙන්න කේත කොටස්:

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;

"අතින් සාදන ලද" මෙම ප්‍රකාශය යෝජනා කරන්නේ මෙම ගොනුවේ කොටසක් පමණක් අතින් ලියා ඇති බවයි (සම්පූර්ණ නඩත්තු බියකරු සිහිනය ඔබට සිතාගත හැකිද?), ඉතිරිය යන්ත්‍ර-උත්පාදනය කරන ලදී. කෙසේ වෙතත්, තවත් ප්රශ්නයක් පැන නගී - මූලාශ්ර තිබේ සම්පූර්ණයෙන්ම නොවේ (ලිනක්ස් කර්නලයේ a la GPL blobs), නමුත් මෙය දැනටමත් දෙවන කොටස සඳහා මාතෘකාවකි.

නමුත් ප්රමාණවත්. අපි මේ සියලුම අනුක්‍රමික ක්‍රියාත්මක වන ප්‍රොටෝකෝලය වෙත යමු.

MTPproto

ඉතින්, අපි විවෘත කරමු සාමාන්ය විස්තරය и ප්රොටෝකෝලය පිළිබඳ සවිස්තරාත්මක විස්තරය අප පැකිළෙන පළමු දෙය පාරිභාෂිතයයි. සහ සෑම දෙයකම බහුලත්වය සමඟ. පොදුවේ ගත් කල, මෙය ටෙලිග්‍රාම් හි හිමිකාර ලක්ෂණයක් ලෙස පෙනේ - විවිධ ස්ථානවල දේවල් වෙනස් ලෙස ඇමතීම, නැතහොත් එක් වචනයකින් විවිධ දේවල්, හෝ අනෙක් අතට (උදාහරණයක් ලෙස, ඉහළ මට්ටමේ API එකක, ඔබ ස්ටිකර් ඇසුරුමක් දුටුවහොත්, එය එසේ නොවේ. ඔබ සිතූ දේ).

උදාහරණයක් ලෙස, "පණිවිඩය" සහ "සැසිය" යන්නෙන් අදහස් කරන්නේ සාමාන්‍ය ටෙලිග්‍රාම් සේවාදායක අතුරුමුහුණතට වඩා වෙනස් දෙයක් මෙහි ය. හොඳයි, පණිවිඩය සමඟ සෑම දෙයක්ම පැහැදිලිය, එය OOP පද වලින් අර්ථ දැක්විය හැකිය, නැතහොත් සරලව "පැකට්ටුව" යන වචනය ලෙස හැඳින්විය හැක - මෙය අඩු, ප්‍රවාහන මට්ටමකි, අතුරු මුහුණතේ මෙන් එකම පණිවිඩ නොමැත, බොහෝ සේවා පණිවිඩ ඇත . නමුත් සැසිය ... නමුත් පළමු දේ පළමුව.

ප්රවාහනය ස්ථරය

පළමු දෙය ප්රවාහනයයි. ඔවුන් අපට විකල්ප 5 ක් ගැන කියනු ඇත:

  • TCP
  • වෙබ්සොකට්
  • HTTPS හරහා Websocket
  • HTTP
  • HTTPS

Vasily, [15.06.18 15:04] UDP ප්‍රවාහනය ද ඇත, නමුත් එය ලේඛනගත නොවේ

සහ TCP ප්‍රභේද තුනකින්

පළමු එක TCP හරහා UDP වලට සමාන වේ, සෑම පැකට්ටුවකම අනුක්‍රමික අංකයක් සහ crc ඇතුළත් වේ
කරත්තයක ලේඛන කියවීම මෙතරම් වේදනාකාරී වන්නේ ඇයි?

හොඳයි, දැන් එය තිබේ TCP දැනටමත් ප්‍රභේද 4කින්:

  • සංක්ෂිප්තයි
  • අතරමැදි
  • පිරවූ අතරමැදි
  • පූර්ණ

හොඳයි, හරි, MTProxy සඳහා Padded අතරමැදි, මෙය සුප්‍රසිද්ධ සිදුවීම් හේතුවෙන් පසුව එකතු කරන ලදී. නමුත් ඔබට එකකින් ලබා ගත හැකි විට තවත් අනුවාද දෙකක් (සම්පූර්ණයෙන් තුනක්) ඇයි? හතරම අත්‍යවශ්‍යයෙන්ම වෙනස් වන්නේ ප්‍රධාන MTProto හි දිග සහ ගෙවීම සකසන්නේ කෙසේද යන්නෙන් පමණි, එය තවදුරටත් සාකච්ඡා කෙරේ:

  • සංක්ෂිප්තයේ එය බයිට් 1ක් හෝ 4ක්, නමුත් 0xef නොවේ, එවිට ශරීරය
  • අතරමැදි මෙය බයිට් 4ක් දිග සහ ක්ෂේත්‍රයක් වන අතර සේවාලාභියා විසින් යැවිය යුතු පළමු අවස්ථාව වේ 0xeeeeeeee එය අතරමැදි බව දැක්වීමට
  • ජාලකරුවෙකුගේ දෘෂ්ටිකෝණයෙන් සම්පූර්ණයෙන්ම ඇබ්බැහි වීම: දිග, අනුක්‍රමික අංකය සහ ප්‍රධාන වශයෙන් MTProto, body, CRC32 එක නොවේ. ඔව්, මේ සියල්ල TCP මත ඇත. අනුක්‍රමික බයිට් ප්‍රවාහයක ස්වරූපයෙන් අපට විශ්වාසදායක ප්‍රවාහනය සපයන්නේ; අනුපිළිවෙලවල් අවශ්‍ය නොවේ, විශේෂයෙන් චෙක්සම්. හරි, දැන් කවුරුහරි මට විරුද්ධ වෙයි TCP සතුව 16-bit චෙක්සම් එකක් තියෙනවා කියලා, ඒ නිසා දත්ත දූෂණය වෙනවා. නියමයි, නමුත් අපට ඇත්ත වශයෙන්ම බයිට් 16කට වඩා දිග හැෂ් සහිත ගුප්ත ලේඛන ප්‍රොටෝකෝලයක් ඇත, මෙම සියලු දෝෂ - සහ ඊටත් වඩා - ඉහළ මට්ටමේ SHA නොගැලපීමකට හසු වනු ඇත. මේක උඩ CRC32 එකේ කිසිම තේරුමක් නෑ.

අපි සංසන්දනය කරමු, එහි එක් බයිටයක් දිග හැකි අතර, එය “බයිට් 4 ක දත්ත පෙළගැස්මක් අවශ්‍ය නම්” සාධාරණීකරණය කරන අතරමැදි සමඟ සංසන්දනය කරමු, එය තරමක් විකාරයකි. කුමක්ද, ටෙලිග්‍රාම් ක්‍රමලේඛකයින් සොකට් එකකින් දත්ත පෙළගස්වන ලද බෆරයකට කියවිය නොහැකි තරම් අදක්ෂ යැයි විශ්වාස කෙරේද? ඔබ තවමත් මෙය කළ යුතුය, මන්ද කියවීමෙන් ඔබට ඕනෑම බයිට් ගණනක් ආපසු ලබා දිය හැකිය (සහ ප්‍රොක්සි සේවාදායකයන් ද ඇත, උදාහරණයක් ලෙස...). එසේත් නැතිනම් අනෙක් අතට, අපට තවමත් බයිට් 16කට වඩා විශාල පිරවුමක් තිබේ නම් - බයිට් 3ක් ඉතිරි කර ගන්නේ නම් සංක්‍ෂිප්තය අවහිර කරන්නේ ඇයි? සමහර විට ?

කිසිදු සැබෑ ප්‍රායෝගික අවශ්‍යතාවයකින් තොරව ජාල ප්‍රොටෝකෝල ඇතුළු රෝද ප්‍රතිනිර්මාණය කිරීමට නිකොලායි ඩුරොව් සැබවින්ම කැමති බව කෙනෙකුට හැඟීමක් ඇති වේ.

වෙනත් ප්රවාහන විකල්ප, ඇතුළුව. Web සහ MTProxy, අපි දැන් සලකා බලන්නේ නැත, සමහර විට වෙනත් පෝස්ට් එකකින්, ඉල්ලීමක් තිබේ නම්. මෙම MTProxy ගැනම, එය 2018 දී නිකුත් කිරීමෙන් ටික කලකට පසු, සපයන්නන් ඉක්මනින් එය අවහිර කිරීමට ඉගෙන ගත් බව පමණක් මතක තබා ගනිමු. බයිපාස් අවහිර කිරීමවිසින් පැකේජය තරම! තවද C හි ලියා ඇති (නැවත Waltman විසින්) MTProxy සේවාදායකය ලිනක්ස් විශේෂතා සමඟ අධික ලෙස බැඳී තිබීම, මෙය කිසිසේත් අවශ්‍ය නොවූවත් (Phil Kulin තහවුරු කරනු ඇත), සහ Go හෝ Node.js හි සමාන සේවාදායකයක් වනු ඇත. පේළි සියයකට වඩා අඩුවෙන් ගැලපේ.

නමුත් අපි මේ අයගේ තාක්ෂණික සාක්ෂරතාවය ගැන නිගමනවලට එළඹෙන්නේ කොටස අවසානයේ, වෙනත් කරුණු සලකා බැලීමෙන් පසුවය. දැනට, අපි OSI ස්ථරය 5 වෙත යමු, සැසිය - ඔවුන් MTProto සැසිය තැබුවා.

යතුරු, පණිවිඩ, සැසි, Diffie-Hellman

ඔවුන් එය එහි තැබුවේ සම්පූර්ණයෙන්ම නිවැරදිව නොවේ... සැසියක් යනු සක්‍රීය සැසි යටතේ අතුරු මුහුණතේ පෙනෙන එකම සැසිය නොවේ. නමුත් පිළිවෙලට.

ටෙලිග්‍රාම් හි ප්‍රොටෝකෝලය සහ සංවිධානාත්මක ප්‍රවේශයන් විවේචනය කිරීම. 1 කොටස, තාක්ෂණික: මුල සිටම සේවාදායකයකු ලිවීමේ අත්දැකීම - TL, MT

ඉතින් අපිට ට්‍රාන්ස්පෝර්ට් ලේයර් එකෙන් දන්න දිග බයිට් ස්ට්‍රිං එකක් ලැබුනා. මෙය සංකේතාත්මක පණිවිඩයක් හෝ සාමාන්‍ය පෙළක් වේ - අප තවමත් ප්‍රධාන ගිවිසුම් අදියරේ සිටින්නේ නම් සහ ඇත්ත වශයෙන්ම එය කරන්නේ නම්. අපි කතා කරන්නේ "යතුර" ලෙස හඳුන්වන සංකල්පවලින් කුමන සංකල්ප ගැනද? අපි මෙම ගැටළුව ටෙලිග්‍රාම් කණ්ඩායම සඳහාම පැහැදිලි කරමු (උදෑසන 4 ට වෙහෙසට පත් මොළයෙන් මගේම ලියකියවිලි ඉංග්‍රීසියෙන් පරිවර්තනය කිරීම ගැන මම සමාව අයදිමි, සමහර වාක්‍ය ඛණ්ඩ එලෙසම තැබීම පහසු විය):

යනුවෙන් ආයතන දෙකක් ඇත වාරය - "වත්මන් සැසි" යටතේ නිල සේවාලාභීන්ගේ UI හි එකක්, සෑම සැසියක්ම සම්පූර්ණ උපාංගයකට / මෙහෙයුම් පද්ධතියකට අනුරූප වේ.
දෙවැන්න නම් MTPproto සැසිය, පණිවිඩයේ අනුක්‍රමික අංකය (පහළ මට්ටමේ අර්ථයකින්) එහි ඇති සහ කුමන විවිධ TCP සම්බන්ධතා අතර පැවතිය හැක. MTProto සැසි කිහිපයක් එකවර ස්ථාපනය කළ හැකිය, උදාහරණයක් ලෙස, ගොනු බාගත කිරීම වේගවත් කිරීම සඳහා.

මේ දෙක අතර සැසිවාර සංකල්පයක් තිබේ අවසරය. පිරිහුණු අවස්ථාවක, අපට එය පැවසිය හැකිය UI සැසිය සමාන වේ අවසරය, නමුත් අහෝ, සියල්ල සංකීර්ණයි. අපි බලමු:

  • නව උපාංගයේ පරිශීලකයා මුලින්ම උත්පාදනය කරයි auth_key සහ එය ගිණුමට බැඳී ඇත, උදාහරණයක් ලෙස SMS හරහා - ඒ නිසයි අවසරය
  • එය පළමු ඇතුළත සිදු විය MTPproto සැසිය, ඇති session_id ඔබ තුළම.
  • මෙම පියවරේදී, සංයෝජනය අවසරය и session_id හැඳින්විය හැක උදාහරණයකි - මෙම වචනය සමහර ගනුදෙනුකරුවන්ගේ ලේඛනවල සහ කේතයේ දිස්වේ
  • එවිට, සේවාදායකයාට විවෘත කළ හැකිය කිහිපයක් ඇත MTPproto සැසි එකම යටතේ auth_key - එකම DC වෙත.
  • ඉන්පසුව, එක් දිනක් සේවාදායකයාට ගොනුව ඉල්ලා සිටීමට අවශ්‍ය වනු ඇත තවත් DC - සහ මෙම DC සඳහා නව එකක් ජනනය කරනු ඇත auth_key !
  • ලියාපදිංචි වන්නේ නව පරිශීලකයෙකු නොවන නමුත් එයම බව පද්ධතියට දැනුම් දීමට අවසරය (UI සැසිය), සේවාදායකයා API ඇමතුම් භාවිතා කරයි auth.exportAuthorization නිවසේ DC auth.importAuthorization නව DC හි.
  • සෑම දෙයක්ම එක හා සමානයි, කිහිපයක් විවෘත විය හැකිය MTPproto සැසි (එක් එක් තමන්ගේම සමග session_id) මෙම නව DC වෙත, යටතේ ඔහුගේ auth_key.
  • අවසාන වශයෙන්, සේවාදායකයාට පරිපූර්ණ ඉදිරි රහස්‍යභාවය අවශ්‍ය විය හැකිය. සෑම auth_key විය ස්ථිර key - per DC - සහ සේවාලාභියාට ඇමතිය හැක auth.bindTempAuthKey භාවිතය සඳහා තාවකාලික auth_key - නැවතත්, එකක් පමණි temp_auth_key DC එකකට, හැමෝටම පොදුයි MTPproto සැසි මෙම DC වෙත.

දැන්වීම ලුණු (සහ අනාගත ලවණ) ද එකකි auth_key එම. හැමෝම අතර බෙදාගත්තා MTPproto සැසි එම DC වෙත.

"විවිධ TCP සම්බන්ධතා අතර" යන්නෙන් අදහස් කරන්නේ කුමක්ද? ඉතින් මේ කියන්නේ වගේ දෙයක් වෙබ් අඩවියක අවසර කුකිය - එය ලබා දී ඇති සේවාදායකයකට බොහෝ TCP සම්බන්ධතා නොනැසී පවතී, නමුත් එක් දිනක් එය නරක අතට හැරේ. HTTP මෙන් නොව, සැසියක් තුළ ඇති MTProto පණිවිඩ අනුක්‍රමිකව අංකනය කර තහවුරු කර ඇත; ඔවුන් උමගට ඇතුළු වූයේ නම්, සම්බන්ධතාවය කැඩී ඇත - නව සම්බන්ධතාවයක් ස්ථාපනය කිරීමෙන් පසු, සේවාදායකයා විසින් පෙර සැසියේදී ලබා නොදුන් සෑම දෙයක්ම කාරුණිකව එවනු ඇත. TCP සම්බන්ධතාවය.

කෙසේ වෙතත්, ඉහත තොරතුරු සාරාංශ කර ඇත්තේ මාස ගණනාවක විමර්ශනයකින් පසුවය. මේ අතර, අපි අපගේ සේවාදායකයා මුල සිටම ක්‍රියාත්මක කරනවාද? - අපි නැවත මුලට යමු.

ඉතින් අපි ජනනය කරමු auth_key මත ටෙලිග්‍රාම් වෙතින් Diffie-Hellman අනුවාද. අපි ලේඛන තේරුම් ගැනීමට උත්සාහ කරමු ...

Vasily, [19.06.18 20:05] data_with_hash := SHA1(දත්ත) + දත්ත + (ඕනෑම අහඹු බයිට්); දිග බයිට් 255 ට සමාන වන පරිදි;
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] මම තවමත් appid ඉල්ලීමට පැමිණ නැත

මම මේ ඉල්ලීම DH වෙත යැව්වා

තවද, ප්‍රවාහන තටාකයේ එය පවසන්නේ දෝෂ කේතයක බයිට් 4කින් ප්‍රතිචාර දැක්විය හැකි බවයි. එච්චරයි

හොඳයි, ඔහු මට කිව්වා -404, ඉතින් මොකක්ද?

එබැවින් මම ඔහුට මෙසේ කීවෙමි: “මේ වගේ ඇඟිලි සලකුණක් සහිත සර්වර් යතුරකින් සංකේතනය කර ඇති ඔබේ ගොන් කතා අල්ලා ගන්න, මට DH අවශ්‍යයි,” එය මෝඩ 404කින් ප්‍රතිචාර දැක්වීය.

මෙම සේවාදායක ප්‍රතිචාරය ගැන ඔබ සිතන්නේ කුමක්ද? කුමක් කරන්න ද? අහන්න කවුරුත් නෑ (හැබැයි ඒ ගැන වැඩි විස්තර දෙවැනි කොටසින්).

මෙහි සියලුම පොලී ඩොක් මත සිදු කෙරේ

මට වෙන කරන්න දෙයක් නෑ, මම හීන දැක්කේ ඉලක්කම් එහාට මෙහාට හරවන්න

බිට් 32 අංක දෙකක්. මම හැමෝම වගේ ඒවා පැක් කළා

ඒත් නෑ මේ දෙක මුලින්ම ලයින් එකට එකතු කරන්න ඕන BE කියල

Vadim Goncharov, [20.06.18 15:49] සහ මේ 404 නිසාද?

Vasily, [20.06.18 15:49] ඔව්!

වඩීම් ගොන්චරොව්, [20.06.18 15:50] ඒ නිසා මට තේරෙන්නේ නැහැ ඔහුට "සොයා නොගත්" දේ

Vasily, [20.06.18 15:50] පමණ වේ

මට එවැනි වියෝජනයක් ප්‍රධාන සාධක බවට සොයා ගැනීමට නොහැකි විය%)

අපි දෝෂ වාර්තා කිරීම පවා කළමනාකරණය කළේ නැත

Vasily, [20.06.18 20:18] ඔහ්, MD5 එකත් තියෙනවා. දැනටමත් විවිධ හැෂ් තුනක්

යතුරු ඇඟිලි සලකුණු පහත පරිදි ගණනය කෙරේ:

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

SHA1 සහ sha2

එහෙනම් දාමු auth_key Diffie-Hellman භාවිතයෙන් අපට බිටු 2048ක් ප්‍රමාණයෙන් ලැබිණි. ඊළඟට කුමක් ද? මීළඟට අපි මෙම යතුරේ පහළ බිටු 1024 කිසිදු ආකාරයකින් භාවිතා නොකරන බව සොයා ගනිමු ... නමුත් අපි දැනට මේ ගැන සිතමු. මෙම පියවරේදී, අපට සේවාදායකය සමඟ හවුල් රහසක් ඇත. TLS සැසියේ ප්රතිසමයක් ස්ථාපිත කර ඇති අතර එය ඉතා මිල අධික ක්රියා පටිපාටියකි. නමුත් සේවාදායකයා තවමත් අප කවුරුන්ද යන්න ගැන කිසිවක් නොදනී! තවමත් නැහැ, ඇත්තටම. අවසරය. එම. ඔබ "පිවිසුම්-මුරපදය" අනුව සිතන්නේ නම්, ඔබ වරක් ICQ හි කළාක් මෙන්, හෝ අවම වශයෙන් "පිවිසුම්-යතුර", SSH හි මෙන් (උදාහරණයක් ලෙස, සමහර gitlab/github මත). අපට නිර්නාමික එකක් ලැබුණා. සේවාදායකයා අපට “මෙම දුරකථන අංක වෙනත් DC මගින් සේවා සපයනු ලැබේ” යැයි පැවසුවහොත් කුමක් කළ යුතුද? නැතහොත් "ඔබේ දුරකථන අංකය තහනම් කර තිබේද"? අපට කළ හැකි හොඳම දෙය නම් යතුර ප්‍රයෝජනවත් වේ යැයි බලාපොරොත්තු වන අතර ඒ වන විට කුණු නොවනු ඇත.

මාර්ගය වන විට, අපි එය වෙන් කිරීම් සමඟ "ලැබුවා". උදාහරණයක් ලෙස, අපි සේවාදායකය විශ්වාස කරනවාද? එය ව්යාජ නම්? ගුප්ත ලේඛන පරීක්ෂාවන් අවශ්‍ය වනු ඇත:

Vasily, [21.06.18 17:53] ඔවුන් ජංගම සේවාලාභීන්ට ප්‍රාථමික% සඳහා 2kbit අංකයක් පරීක්ෂා කිරීමට ඉදිරිපත් කරයි)

නමුත් එය කිසිසේත්ම පැහැදිලි නැත, nafeijoa

Vasily, [21.06.18 18:02] ලේඛනය සරල නොවන බව පෙනී ගියහොත් කුමක් කළ යුතු දැයි නොකියයි

කිව්වේ නැහැ. මෙම නඩුවේ නිල ඇන්ඩ්රොයිඩ් සේවාදායකයා කරන්නේ කුමක්දැයි බලමු? ඒ ඒක තමයි (ඔව්, සම්පූර්ණ ගොනුව රසවත්) - ඔවුන් පවසන පරිදි, මම මෙය මෙහි තබමි:

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

නැත, ඇත්ත වශයෙන්ම එය තවමත් පවතී ඇතැම් සංඛ්‍යාවක ප්‍රාථමිකත්වය සඳහා පරීක්ෂණ ඇත, නමුත් පුද්ගලිකව මට තවදුරටත් ගණිතය පිළිබඳ ප්‍රමාණවත් දැනුමක් නොමැත.

හරි, අපි ප්රධාන යතුර ලබා ගත්තා. පුරනය වීමට, i.e. ඉල්ලීම් යවන්න, ඔබ AES භාවිතයෙන් වැඩිදුර සංකේතනය කිරීමට අවශ්‍ය වේ.

පණිවිඩ යතුර යනු බලය පැවරීමේ යතුරෙන් ලබාගත් බයිට් 128 කින් පූර්වයෙන් සකස් කරන ලද පැඩින් බයිට් ඇතුළුව (සැසිය, පණිවිඩ හැඳුනුම්පත, ආදිය ඇතුළුව) පණිවිඩ අන්තර්ගතයේ SHA256 හි මැද බිටු 32 ලෙස අර්ථ දැක්වේ.

Vasily, [22.06.18 14:08] සාමාන්‍ය, බැල්ලි, බිටු

ලැබුනා auth_key. සෑම. ඔවුන්ගෙන් ඔබ්බට ... එය ලේඛනයෙන් පැහැදිලි නැත. විවෘත කේත අධ්‍යයනය කිරීමට නිදහස් වන්න.

MTProto 2.0 ට පැඩින් බයිට් 12 සිට 1024 දක්වා අවශ්‍ය බව සලකන්න, තවමත් ලැබෙන පණිවිඩ දිග බයිට් 16 කින් බෙදිය හැකි බවට කොන්දේසියට යටත් වේ.

ඉතින් ඔබ කොපමණ පිරවුම් එකතු කළ යුතුද?

ඔව්, දෝෂයක් ඇති වුවහොත් 404 ද ඇත

යමෙක් ලේඛනයේ රූප සටහන සහ පෙළ හොඳින් අධ්‍යයනය කළේ නම්, එහි MAC නොමැති බව ඔවුන්ට පෙනී ගියේය. තවද AES භාවිතා කරනු ලබන්නේ වෙනත් කිසිම තැනක භාවිතා නොකරන යම් IGE මාදිලියක ය. ඔවුන්, ඇත්ත වශයෙන්ම, ඔවුන්ගේ නිති අසන ප්‍රශ්නවල මේ ගැන ලියයි... මෙන්න, පණිවිඩ යතුර ම, විසංකේතනය කළ දත්තවල SHA හැෂ් ද වේ, අඛණ්ඩතාව පරීක්ෂා කිරීමට භාවිතා කරයි - සහ නොගැලපීමකදී, කිසියම් හේතුවක් නිසා ලේඛනගත කිරීම ඔවුන් නිශ්ශබ්දව නොසලකා හැරීම නිර්දේශ කරයි (නමුත් ආරක්ෂාව ගැන කුමක් කිව හැකිද, ඔවුන් අපව බිඳ දැමුවහොත් කුමක් කළ යුතුද?).

මම ගුප්ත ලේඛන ශිල්පියෙක් නොවේ, සමහර විට න්‍යායාත්මක දෘෂ්ටි කෝණයකින් මෙම නඩුවේ මෙම මාදිලියේ කිසිදු වරදක් නොමැත. නමුත් ටෙලිග්‍රාම් ඩෙස්ක්ටොප් එක උදාහරණයක් ලෙස භාවිතා කරමින් මට ප්‍රායෝගික ගැටලුවක් පැහැදිලිව නම් කළ හැකිය. එය දේශීය හැඹිලිය (මේ සියල්ල D877F783D5D3EF8C) MTProto හි පණිවිඩ මෙන් සංකේතනය කරයි (මෙම අවස්ථාවෙහි අනුවාදය 1.0 පමණි), i.e. පළමුව පණිවිඩ යතුර, පසුව දත්තම (සහ කොතැනක හෝ ප්‍රධාන විශාලය auth_key බයිට් 256 ක්, එය නොමැතිව msg_key නිෂ්ඵල). එබැවින්, විශාල ලිපිගොනු මත ගැටළුව කැපී පෙනේ. එනම්, ඔබ දත්තවල පිටපත් දෙකක් තබා ගත යුතුය - සංකේතාත්මක සහ විකේතනය කර ඇත. සහ මෙගාබයිට් හෝ ප්‍රවාහ වීඩියෝ තිබේ නම්, උදාහරණයක් ලෙස?.. කේතාංකයෙන් පසුව MAC සමඟ ඇති සම්භාව්‍ය යෝජනා ක්‍රම ඔබට එය ප්‍රවාහය කියවීමට ඉඩ සලසයි, එය වහාම සම්ප්‍රේෂණය කරයි. නමුත් MTProto සමඟ ඔබට සිදු වනු ඇත මුලදී සම්පූර්ණ පණිවිඩය සංකේතනය කරන්න හෝ විකේතනය කරන්න, පසුව පමණක් එය ජාලයට හෝ තැටියට මාරු කරන්න. එබැවින්, හැඹිලියේ ඇති Telegram Desktop හි නවතම අනුවාද වල user_data තවත් ආකෘතියක් ද භාවිතා වේ - CTR මාදිලියේ AES සමඟ.

Vasily, [21.06.18 01:27] ඔහ්, මම IGE යනු කුමක්දැයි සොයා ගතිමි: IGE යනු Kerberos සඳහා "සත්‍යාපනය කිරීමේ සංකේතාංකන මාදිලියේ" පළමු උත්සාහයයි. එය අසාර්ථක උත්සාහයක් (එය අඛණ්ඩතාව ආරක්ෂාව සපයන්නේ නැත), සහ ඉවත් කිරීමට සිදු විය. එය OCB සහ GCM වැනි ක්‍රම වලින් මෑතකදී අවසන් වූ, ක්‍රියාත්මක වන සත්‍යාපන සංකේතාංකන මාදිලියක් සඳහා වසර 20ක ගවේෂණයක ආරම්භය විය.

දැන් කරත්ත පැත්තෙන් තර්ක:

නිකොලායි ඩුරොව්ගේ නායකත්වයෙන් යුත් ටෙලිග්‍රාම් පිටුපස සිටින කණ්ඩායම ACM ශූරයන් හය දෙනෙකුගෙන් සමන්විත වන අතර ඔවුන්ගෙන් අඩක් ගණිතය පිළිබඳ ආචාර්ය උපාධිධාරීන් වේ. MTProto හි වත්මන් අනුවාදය නිකුත් කිරීමට ඔවුන්ට වසර දෙකක් පමණ ගත විය.

එය සිනහ උපදවයි. පහළ මට්ටමේ අවුරුදු දෙකක්

නැත්නම් tls ගන්න පුළුවන්

හරි, අපි කියමු අපි සංකේතනය සහ අනෙකුත් සූක්ෂ්ම දේ කළා කියලා. අවසාන වශයෙන් TL හි අනුක්‍රමික ඉල්ලීම් යැවීමට සහ ප්‍රතිචාර ඉවත් කිරීමට හැකිද? ඉතින් ඔබ යැවිය යුත්තේ කුමක්ද සහ කෙසේද? මෙන්න, අපි කියමු, ක්රමය initConnection, සමහරවිට මේකද?

Vasily, [25.06.18 18:46] සම්බන්ධතාවය ආරම්භ කර පරිශීලකයාගේ උපාංගයේ සහ යෙදුමේ තොරතුරු සුරකියි.

එය app_id, device_model, system_version, app_version සහ lang_code පිළිගනී.

සහ සමහර විමසුම්

සෑම විටම මෙන් ලේඛනගත කිරීම. විවෘත මූලාශ්‍රය අධ්‍යයනය කිරීමට නිදහස් වන්න

InvokeWithLayer සමඟින් සියල්ල ආසන්න වශයෙන් පැහැදිලි නම්, මෙහි ඇති වරද කුමක්ද? එය හැරෙනවා, අපි කියමු - සේවාදායකයාට දැනටමත් සේවාදායකයෙන් යමක් ඇසීමට යමක් තිබේ - අපට යැවීමට අවශ්‍ය ඉල්ලීමක් තිබේ:

Vasily, [25.06.18 19:13] කේතය අනුව විනිශ්චය කිරීම, පළමු ඇමතුම මෙම ජරාව තුළ ඔතා ඇති අතර, ජරාවම invokewithlayer එකකින් ඔතා ඇත.

initConnection වෙනම ඇමතුමක් විය නොහැකි නමුත්, එය දවටනයක් විය යුත්තේ ඇයි? ඔව්, එය සිදු වූ පරිදි, එය එක් එක් සැසියේ ආරම්භයේ සෑම අවස්ථාවකදීම සිදු කළ යුතු අතර, ප්රධාන යතුර මෙන් එක් වරක් නොවේ. එහෙත්! එය අනවසර පරිශීලකයෙකු විසින් ඇමතිය නොහැක! දැන් අපි එය අදාළ වන මට්ටමට පැමිණ ඇත මේක ලේඛන පිටුව - සහ එය අපට පවසන්නේ ...

API ක්‍රම වලින් කුඩා කොටසක් පමණක් අනවසර පරිශීලකයින්ට ලබා ගත හැක:

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

ඔවුන්ගෙන් පළමුවැන්න, auth.sendCode, සහ අපි api_id සහ api_hash යවන ආදරණීය පළමු ඉල්ලීම ඇත, ඉන්පසු අපට කේතයක් සහිත SMS එකක් ලැබේ. අප වැරදි DC එකක සිටී නම් (මේ රටේ දුරකථන අංක වෙනත් අයෙකු විසින් සපයනු ලැබේ, උදාහරණයක් ලෙස), එවිට අපට අපේක්ෂිත DC අංකය සමඟ දෝෂයක් ලැබෙනු ඇත. ඔබට සම්බන්ධ විය යුතු DC අංකයෙන් කුමන IP ලිපිනයද යන්න සොයා ගැනීමට, අපට උදවු කරන්න help.getConfig. වරෙක ඇතුළත් කිරීම් 5 ක් පමණක් තිබුනද, 2018 සුප්‍රසිද්ධ සිදුවීම් වලින් පසුව, එම සංඛ්‍යාව සැලකිය යුතු ලෙස වැඩි වී තිබේ.

දැන් අපි මතක තබා ගනිමු අපි නිර්නාමිකව සේවාදායකයේ මෙම අදියරට පැමිණි බව. නිකන් IP address එකක් ගන්න එක වියදම් වැඩියි නේද? MTProto හි සංකේතනය නොකළ කොටසෙහි මෙය සහ අනෙකුත් මෙහෙයුම් සිදු නොකරන්නේ මන්ද? මට විරුද්ධත්වය ඇහෙනවා: "ව්‍යාජ ලිපින වලින් ප්‍රතිචාර දක්වන්නේ RKN නොවන බව අපි සහතික කර ගන්නේ කෙසේද?" මේ සඳහා අපි සාමාන්යයෙන්, නිල ගනුදෙනුකරුවන් බව මතක තබා ගන්න RSA යතුරු එබ්බවා ඇත, i.e. ඔබට පුළුවන්ද දායක වන්න මෙම තොරතුරු. ඇත්ත වශයෙන්ම, මෙය දැනටමත් වෙනත් නාලිකා හරහා සේවාදායකයින්ට ලැබෙන අවහිර කිරීම් මඟ හැරීම පිළිබඳ තොරතුරු සඳහා සිදු කෙරේ (තර්කානුකූලව, මෙය MTProto තුළම කළ නොහැක; සම්බන්ධ විය යුත්තේ කොතැනටද යන්න ඔබ දැනගත යුතුය).

හරි. සේවාලාභී අවසරයේ මෙම අදියරේදී, අපට තවමත් අවසර දී නොමැති අතර අපගේ අයදුම්පත ලියාපදිංචි කර නොමැත. අනවසර පරිශීලකයෙකුට ලබා ගත හැකි ක්‍රමවලට සේවාදායකය ප්‍රතිචාර දක්වන්නේ කුමක් දැයි අපට දැන් බැලීමට අවශ්‍යය. මෙහි…

Vasily, [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 schema හි තුන්වන අගය වේ

ඔව්, එතැන් සිට, ඇත්ත වශයෙන්ම, ලේඛන යාවත්කාලීන කර ඇත. එය ඉතා ඉක්මනින් නැවත අදාළ නොවන බවට පත් විය හැකි වුවද. නවක සංවර්ධකයෙකු දැනගත යුත්තේ කෙසේද? සමහර විට ඔබ ඔබේ අයදුම්පත ලියාපදිංචි කළහොත්, ඔවුන් ඔබට දැනුම් දෙනු ඇත? වාසිලි මෙය කළා, නමුත් අහෝ, ඔවුන් ඔහුට කිසිවක් යැව්වේ නැත (නැවතත්, අපි මේ ගැන දෙවන කොටසෙන් කතා කරමු).

...අපි දැනටමත් කෙසේ හෝ API වෙත ගොස් ඇති බව ඔබ දැක ඇත, එනම්. මීළඟ මට්ටමට, සහ MTProto මාතෘකාවේ යමක් මග හැරුණාද? පුදුමයක් නැත:

Vasily, [28.06.18 02:04] ම්ම්ම්, ඔවුන් e2e හි සමහර ඇල්ගොරිතම හරහා ගැවසෙමින් සිටී

Mtproto වසම් දෙකම සඳහා සංකේතාංකන ඇල්ගොරිතම සහ යතුරු, මෙන්ම දවටන ව්‍යුහයක් නිර්වචනය කරයි

නමුත් ඒවා නිරන්තරයෙන් විවිධ මට්ටම් තොග මිශ්‍ර කරයි, එබැවින් mtproto අවසන් වූයේ කොතැනින්ද සහ ඊළඟ මට්ටම ආරම්භ වූයේ කොතැනින්ද යන්න සැමවිටම පැහැදිලි නැත.

ඔවුන් මිශ්ර කරන්නේ කෙසේද? හොඳයි, මෙන්න PFS සඳහා එකම තාවකාලික යතුරයි, උදාහරණයක් ලෙස (මාර්ගය වන විට, ටෙලිග්‍රාම් ඩෙස්ක්ටොප් එකට එය කළ නොහැක). එය API ඉල්ලීමක් මඟින් ක්‍රියාත්මක වේ auth.bindTempAuthKey, i.e. ඉහළ මට්ටමේ සිට. නමුත් ඒ සමඟම එය පහළ මට්ටමේ සංකේතනයට බාධා කරයි - ඊට පසු, උදාහරණයක් ලෙස, ඔබ එය නැවත කළ යුතුය initConnection ආදිය, මෙය නොවේ සාධාරණයි සාමාන්ය ඉල්ලීම. විශේෂත්වය නම්, ඔබට ක්ෂේත්‍රය වුවද, DC එකකට එක් තාවකාලික යතුරක් පමණක් තිබිය හැක auth_key_id සෑම පණිවිඩයකම අවම වශයෙන් සෑම පණිවිඩයක්ම යතුර වෙනස් කිරීමට ඔබට ඉඩ සලසයි, සහ සේවාදායකයට ඕනෑම වේලාවක තාවකාලික යතුර "අමතක" කිරීමට අයිතියක් ඇති බව - මෙම නඩුවේ කුමක් කළ යුතු දැයි ලියකියවිලි නොකියයි ... හොඳයි, ඇයි හැකි වූයේ අනාගත ලවණ කට්ටලයක් මෙන් ඔබට යතුරු කිහිපයක් තිබේද?..

MTProto තේමාව ගැන සඳහන් කළ යුතු තවත් කරුණු කිහිපයක් තිබේ.

පණිවිඩ පණිවිඩ, msg_id, msg_seqno, තහවුරු කිරීම්, වැරදි දිශාවට pings සහ වෙනත් idiosyncrasies

ඔබ ඔවුන් ගැන දැනගත යුත්තේ ඇයි? ඔවුන් ඉහළ මට්ටමකට "කාන්දු" වන නිසා, API සමඟ වැඩ කිරීමේදී ඔබ ඔවුන් ගැන දැනුවත් විය යුතුය. අපි උපකල්පනය කරමු අපි msg_key ගැන උනන්දුවක් නොදක්වමු; පහළ මට්ටම අප වෙනුවෙන් සියල්ල විකේතනය කර ඇත. නමුත් විකේතනය කරන ලද දත්ත තුළ අපට පහත ක්ෂේත්‍ර ඇත (දත්තවල දිගද, ඒ නිසා පෑඩින් එක කොතැනදැයි අපි දනිමු, නමුත් එය වැදගත් නොවේ):

  • ලුණු - int64
  • session_id - int64
  • message_id - int64
  • seq_no - int32

සම්පූර්ණ DC සඳහා ඇත්තේ එක් ලුණු පමණක් බව අපි ඔබට මතක් කරමු. ඇය ගැන දන්නේ ඇයි? ඉල්ලීමක් තිබෙන නිසාම නොවේ get_future_salts, එය වලංගු වන්නේ කුමන කාල පරතරයන්දැයි ඔබට කියයි, නමුත් ඔබේ ලුණු “කුණු” නම්, පණිවිඩය (ඉල්ලීම) සරලව නැති වී යනු ඇත. සේවාදායකයා, ඇත්ත වශයෙන්ම, නිකුත් කිරීමෙන් නව ලුණු වාර්තා කරනු ඇත new_session_created - නමුත් පැරණි එක සමඟ ඔබට එය කෙසේ හෝ නැවත යැවීමට සිදුවනු ඇත, උදාහරණයක් ලෙස. තවද මෙම ගැටළුව යෙදුම් ගෘහ නිර්මාණ ශිල්පයට බලපායි.

සේවාදායකයට සැසි සම්පූර්ණයෙන්ම අත්හැරීමට සහ බොහෝ හේතු නිසා මේ ආකාරයෙන් ප්‍රතිචාර දැක්වීමට අවසර ඇත. ඇත්ත වශයෙන්ම, සේවාලාභියාගේ පැත්තෙන් MTProto සැසියක් යනු කුමක්ද? මේවා අංක දෙකකි session_id и seq_no මෙම සැසිය තුළ පණිවිඩ. හොඳයි, සහ යටින් පවතින TCP සම්බන්ධතාවය, ඇත්ත වශයෙන්ම. අපගේ සේවාදායකයා තවමත් බොහෝ දේ කරන්නේ කෙසේදැයි නොදන්නා බව කියමු, ඔහු විසන්ධි කර නැවත සම්බන්ධ විය. මෙය ඉක්මනින් සිදු වූවා නම් - පැරණි සැසිය නව TCP සම්බන්ධතාවයේ දිගටම පැවතුනි, වැඩි කරන්න seq_no තව දුරටත්. එය දිගු කාලයක් ගත වුවහොත්, සේවාදායකයට එය මකා දැමිය හැකිය, මන්ද එහි පැත්තේද එය පෝලිමකි, අපි සොයා ගත් පරිදි.

එය කුමක් විය යුතුද seq_no? ඔහ්, ඒක කපටි ප්‍රශ්නයක්. අදහස් කළ දේ අවංකව තේරුම් ගැනීමට උත්සාහ කරන්න:

අන්තර්ගතයට අදාළ පණිවිඩය

පැහැදිලි පිළිගැනීමක් අවශ්‍ය පණිවිඩයක්. මේවාට සියලුම පරිශීලකයින් සහ බොහෝ සේවා පණිවිඩ ඇතුළත් වේ, බහාලුම් සහ පිළිගැනීම් හැරුණු විට සියල්ලම පාහේ.

පණිවිඩ අනුක්‍රමික අංකය (msg_seqno)

"අන්තර්ගතයට අදාළ" පණිවිඩ සංඛ්‍යාව මෙන් දෙගුණයකට සමාන 32-බිට් සංඛ්‍යාවක් (පිළිගැනීම අවශ්‍ය ඒවා සහ විශේෂයෙන් බහාලුම් නොවන ඒවා) යවන්නා විසින් මෙම පණිවිඩයට පෙර නිර්මාණය කර පසුව වත්මන් පණිවිඩය නම් එකකින් වැඩි කළ අන්තර්ගතයට අදාළ පණිවිඩය. කන්ටේනරයක් සෑම විටම එහි සම්පූර්ණ අන්තර්ගතයෙන් පසුව ජනනය වේ; එබැවින් එහි අනුක්‍රමික අංකය එහි අඩංගු පණිවිඩවල අනුක්‍රමික අංකවලට වඩා වැඩි හෝ සමාන වේ.

මෙය 1 න් වර්ධකයක් සහ තවත් 2 කින් වර්ධකයක් සහිත කුමන ආකාරයේ සර්කස් එකක් ද?.. මම සැක කරන්නේ මුලදී ඔවුන් අදහස් කළේ “ACK සඳහා අවම වැදගත්කම, ඉතිරිය සංඛ්‍යාවකි”, නමුත් ප්‍රති result ලය සමාන නොවේ - විශේෂයෙන්, එය පිටතට පැමිණේ, යැවිය හැක කිහිපයක් ඇත තහවුරු කිරීම් සමාන වේ seq_no! කෙසේද? හොඳයි, උදාහරණයක් ලෙස, සේවාදායකය අපට යමක් එවයි, එය යවයි, සහ අපි නිශ්ශබ්දව සිටිමු, එහි පණිවිඩ ලැබීම තහවුරු කරන සේවා පණිවිඩ සමඟ පමණක් ප්‍රතිචාර දක්වයි. මෙම අවස්ථාවේදී, අපගේ පිටතට යන තහවුරු කිරීම් වලට එකම පිටතට යන අංකයක් ඇත. ඔබ TCP ගැන හුරුපුරුදු නම් සහ මෙය කෙසේ හෝ වල් ලෙස පෙනේ යැයි සිතන්නේ නම්, නමුත් එය එතරම් වල් නොවන බව පෙනේ, මන්ද TCP හි seq_no වෙනස් නොවේ, නමුත් තහවුරු කිරීම වෙත යයි seq_no අනෙක් පැත්තෙන්, මම ඔබව කලබල කිරීමට ඉක්මන් කරන්නෙමි. MTProto හි තහවුරු කිරීම් සපයනු ලැබේ නෙ මත seq_no, TCP හි මෙන්, නමුත් විසින් msg_id !

මේ කුමක් ද msg_id, මෙම ක්ෂේත්‍රවලින් වඩාත්ම වැදගත් වන්නේ? නමට අනුව අනන්‍ය පණිවිඩ හඳුනාගැනීමක්. එය 64-bit අංකයක් ලෙස අර්ථ දක්වා ඇත, එහි අඩුම බිටුවල නැවතත් “සේවාදායක-නොවන-සේවාදායක” මැජික් ඇති අතර ඉතිරිය Unix වේලා මුද්‍රාවකි, භාගික කොටස ඇතුළුව, බිටු 32 ක් වමට මාරු කර ඇත. එම. කාලමුද්‍රාව අනුව (සහ බොහෝ වෙනස් වන වේලාවන් සහිත පණිවිඩ සේවාදායකය විසින් ප්‍රතික්ෂේප කරනු ලැබේ). මෙයින් පෙනී යන්නේ පොදුවේ මෙය සේවාදායකයා සඳහා ගෝලීය හඳුනාගැනීමක් බවයි. එය ලබා දී - අපි මතක තබා ගනිමු session_id - අපට සහතිකයි: කිසිම අවස්ථාවක එක් සැසියක් සඳහා වූ පණිවිඩයක් වෙනත් සැසියකට යැවිය නොහැක. එනම්, දැනටමත් ඇති බව පෙනී යයි තුනකි මට්ටම - සැසිය, සැසි අංකය, පණිවිඩ හැඳුනුම්පත. මෙතරම් සංකීර්ණ වන්නේ ඇයි, මෙම අභිරහස ඉතා විශිෂ්ටයි.

එසේ නම්, msg_id සඳහා අවශ්‍ය...

RPC: ඉල්ලීම්, ප්‍රතිචාර, දෝෂ. තහවුරු කිරීම්.

ඔබ දැක ඇති පරිදි, පිළිතුරු ඇතත්, රූප සටහනේ කොතැනකවත් විශේෂ "RPC ඉල්ලීමක් කරන්න" වර්ගයක් හෝ ක්‍රියාකාරීත්වයක් නොමැත. සියල්ලට පසු, අපට අන්තර්ගතයට අදාළ පණිවිඩ තිබේ! එනම්, ඕනෑම පණිවිඩය ඉල්ලීමක් විය හැකිය! නැත්නම් වෙන්න එපා. සියල්ලට පසු, එකිනෙකාmsg_id. නමුත් පිළිතුරු තිබේ:

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

මෙය කුමන පණිවිඩයකට ප්‍රතිචාරයක් දැයි පෙන්වා දෙන්නේ මෙහිදීය. එබැවින්, API හි ඉහළ මට්ටමේ, ඔබගේ ඉල්ලීමේ අංකය කුමක්දැයි ඔබට මතක තබා ගැනීමට සිදුවනු ඇත - කාර්යය අසමමුහුර්ත බව පැහැදිලි කිරීමට අවශ්‍ය නැත, සහ එකවර ඉල්ලීම් කිහිපයක් ක්‍රියාත්මක විය හැකිය, ඕනෑම අනුපිළිවෙලකට ආපසු ලබා දිය හැකි පිළිතුරු මොනවාද? ප්‍රතිපත්තිමය වශයෙන්, මෙයින් සහ කම්කරුවන් නොමැති වැනි දෝෂ පණිවිඩ වලින්, මෙය පිටුපස ඇති ගෘහ නිර්මාණ ශිල්පය සොයා ගත හැක: ඔබ සමඟ TCP සම්බන්ධතාවයක් පවත්වාගෙන යන සේවාදායකය ඉදිරිපස සමතුලිතයෙකු වේ, එය ඉල්ලීම් පසුපෙළ වෙත යොමු කර ඒවා හරහා ආපසු එකතු කරයි. message_id. මෙහි සෑම දෙයක්ම පැහැදිලි, තර්කානුකූල සහ හොඳ බව පෙනේ.

ඔව්?.. ඒ වගේම හිතුවොත්? සියල්ලට පසු, RPC ප්‍රතිචාරයටම ක්ෂේත්‍රයක් ඇත msg_id! “ඔබ මගේ පිළිතුරට පිළිතුරු දෙන්නේ නැත!” යනුවෙන් අපි සේවාදායකයට කෑ ගැසීමට අවශ්‍යද? ඔව්, තහවුරු කිරීම් ගැන තිබුණේ කුමක්ද? පිටුව ගැන පණිවිඩ පිළිබඳ පණිවිඩ යනු කුමක්දැයි අපට කියයි

msgs_ack#62d6b459 msg_ids:Vector long = MsgsAck;

තවද එය එක් එක් පැත්තෙන් සිදු කළ යුතුය. නමුත් සෑම විටම නොවේ! ඔබට RpcResult ලැබුනේ නම්, එයම තහවුරු කිරීමක් ලෙස ක්‍රියා කරයි. එනම්, සේවාදායකයට MsgsAck සමඟින් ඔබේ ඉල්ලීමට ප්‍රතිචාර දැක්විය හැක - වැනි, "මට එය ලැබුණා." RpcResult වහාම ප්රතිචාර දැක්විය හැක. එය දෙකම විය හැකිය.

ඔව්, ඔබ තවමත් පිළිතුරට පිළිතුරු දිය යුතුය! තහවුරු කිරීම. එසේ නොමැති නම්, සේවාදායකය එය ලබා දිය නොහැකි යැයි සලකනු ලබන අතර එය නැවත ඔබ වෙත එවනු ඇත. නැවත සම්බන්ධ වීමෙන් පසුව පවා. නමුත් මෙන්න, ඇත්ත වශයෙන්ම, කල් ඉකුත්වීම පිළිබඳ ගැටළුව පැන නගී. අපි ඒවා ටිකක් පසුව බලමු.

මේ අතරතුර, විය හැකි විමසුම් ක්රියාත්මක කිරීමේ දෝෂ දෙස බලමු.

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

ඔහ්, යමෙකු කෑගසනු ඇත, මෙන්න වඩාත් මානුෂීය ආකෘතියක් - රේඛාවක් තිබේ! ඔයාගේ කාලය ගන්න. මෙතන දෝෂ ලැයිස්තුව, නමුත් ඇත්ත වශයෙන්ම සම්පූර්ණ නොවේ. ඒකෙන් අපි ඉගෙන ගන්නවා code එක කියලා වගේ දෙයක් HTTP දෝෂ (හොඳයි, ඇත්ත වශයෙන්ම, ප්‍රතිචාරවල අර්ථ නිරූපණයට ගරු නොකෙරේ, සමහර ස්ථානවල ඒවා කේත අතර අහඹු ලෙස බෙදා හරිනු ලැබේ), සහ රේඛාව මේ වගේ ය CAPITAL_LETTERS_AND_NUMBERS. උදාහරණයක් ලෙස, PHONE_NUMBER_OCCUPIED හෝ FILE_PART_Х_MISSING. හොඳයි, එනම්, ඔබට තවමත් මෙම රේඛාව අවශ්ය වනු ඇත විග්‍රහ කරන්න. උදාහරණයක් ලෙස FLOOD_WAIT_3600 එයින් අදහස් වන්නේ ඔබ පැයක් බලා සිටිය යුතු බවයි, සහ PHONE_MIGRATE_5, මෙම උපසර්ගය සහිත දුරකථන අංකයක් 5 වැනි DC හි ලියාපදිංචි කළ යුතු බව. අපිට තියෙන්නේ type language එකක් නේද? අපට තන්තුවකින් තර්කයක් අවශ්‍ය නැත, සාමාන්‍ය අය කරනු ඇත, හරි.

නැවතත්, මෙය සේවා පණිවිඩ පිටුවේ නැත, නමුත්, මෙම ව්යාපෘතිය සමඟ දැනටමත් සුපුරුදු පරිදි, තොරතුරු සොයාගත හැකිය වෙනත් ලේඛන පිටුවක. නැත්නම් සැක පහළ කරයි. පළමුව, බලන්න, ටයිප් කිරීම/ස්ථර උල්ලංඝනය - RpcError තුළ කූඩු කළ හැක RpcResult. ඇයි එළියේ නැත්තේ? අපි ගණන් නොගත්තෙ මොනවද?.. ඒ අනුව කෝ ඒ සහතිකය RpcError තුළ අන්තර්ගත නොවිය හැක RpcResult, නමුත් සෘජුව හෝ වෙනත් වර්ගයක කූඩු කළ හැකිද?.. සහ එය කළ නොහැකි නම්, එය ඉහළ මට්ටමේ නැත්තේ ඇයි, i.e. එය අතුරුදහන් වේ req_msg_id ? ..

නමුත් අපි සේවා පණිවිඩ ගැන දිගටම කරගෙන යමු. සේවාදායකයා දිගු වේලාවක් කල්පනා කරන බව සේවාදායකයා සිතන අතර මෙම අපූරු ඉල්ලීම කරන්න:

rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;

මෙම ප්‍රශ්නයට පිළිතුරු තුනක් ඇත, නැවත තහවුරු කිරීමේ යාන්ත්‍රණය සමඟ ඡේදනය වේ; ඒවා කුමක් විය යුතුද යන්න තේරුම් ගැනීමට උත්සාහ කිරීම (සහ තහවුරු කිරීම අවශ්‍ය නොවන වර්ගවල සාමාන්‍ය ලැයිස්තුව කුමක්ද) ගෙදර වැඩ ලෙස පාඨකයාට ඉතිරි වේ (සටහන: තොරතුරු ටෙලිග්‍රාම් ඩෙස්ක්ටොප් ප්‍රභව කේතය සම්පූර්ණ නැත).

මත්ද්‍රව්‍යවලට ඇබ්බැහි වීම: පණිවිඩ තත්ව

පොදුවේ ගත් කල, TL, MTProto සහ Telegram හි බොහෝ ස්ථාන මුරණ්ඩුකමේ හැඟීමක් ඇති කරයි, නමුත් ආචාරශීලී බව, උපාය සහ වෙනත් අය නිසා මෘදු කුසලතා අපි ඒ ගැන විනීතව මුනිවත රකිමින්, දෙබස්වල ඇති කුණුහරුප වාරණය කළෙමු. කෙසේ වෙතත්, මෙම ස්ථානයОපිටුවේ වැඩි හරියක් ගැන පණිවිඩ පිළිබඳ පණිවිඩ දිගු කලක් ජාල ප්‍රොටෝකෝල සමඟ වැඩ කර ඇති සහ විවිධ මට්ටම්වල වක්‍ර බයිසිකල් දැක ඇති මට පවා එය කම්පනයකි.

එය නිර්දෝෂී ලෙස, තහවුරු කිරීම් සමඟ ආරම්භ වේ. ඊළඟට ඔවුන් අපට කියනවා

bad_msg_notification#a7eff811 bad_msg_id:long bad_msg_seqno:int error_code:int = BadMsgNotification;
bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification;

හොඳයි, MTProto සමඟ වැඩ කිරීමට පටන් ගන්නා සෑම කෙනෙකුටම ඔවුන් සමඟ කටයුතු කිරීමට සිදුවනු ඇත; "නිවැරදි කරන ලද - නැවත සකස් කරන ලද - දියත් කරන ලද" චක්‍රය තුළ, සංස්කරණ අතරතුර නරක වීමට සමත් වූ සංඛ්‍යා දෝෂ හෝ ලුණු ලබා ගැනීම සාමාන්‍ය දෙයකි. කෙසේ වෙතත්, මෙහි කරුණු දෙකක් තිබේ:

  1. මෙයින් අදහස් කරන්නේ මුල් පණිවිඩය නැති වී ඇති බවයි. අපට පෝලිම් කිහිපයක් සෑදිය යුතුය, අපි එය පසුව බලමු.
  2. මොනවද මේ අමුතු දෝෂ අංක? 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 64... කෝ අනිත් ඉලක්කම් ටොමී?

ලේඛනයේ මෙසේ සඳහන් වේ.

අභිප්‍රාය වන්නේ දෝෂ_කේත අගයන් කාණ්ඩගත කර තිබීමයි (error_code >> 4): උදාහරණයක් ලෙස, 0x40 - 0x4f කේත බහාලුම් වියෝජනයේ දෝෂ වලට අනුරූප වේ.

නමුත්, පළමුව, අනෙක් දිශාවට මාරුවීමක්, සහ දෙවනුව, එය වැදගත් නොවේ, අනෙක් කේත කොහෙද? කතුවරයාගේ හිසෙහි?.. කෙසේ වෙතත්, මේවා ට්රයිෆල් ය.

ඇබ්බැහි වීම ආරම්භ වන්නේ පණිවිඩ තත්ත්‍වයන් සහ පණිවිඩ පිටපත් පිළිබඳ පණිවිඩවලිනි:

  • පණිවිඩ තත්ව තොරතුරු සඳහා ඉල්ලීම
    කිසියම් පාර්ශ්වයකට තම පිටතට යන පණිවිඩවල තත්ත්වය පිළිබඳ තොරතුරු ටික වේලාවක් නොලැබුනේ නම්, එය අනෙක් පාර්ශ්වයෙන් එය පැහැදිලිවම ඉල්ලා සිටිය හැක:
    msgs_state_req#da69fb52 msg_ids:Vector long = MsgsStateReq;
  • පණිවිඩවල තත්ත්වය පිළිබඳ තොරතුරු පණිවිඩය
    msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;
    මෙහි, info එන msg_ids ලැයිස්තුවෙන් සෑම පණිවිඩයක් සඳහාම හරියටම එක් බයිටයක පණිවිඩ තත්ත්‍වයක් අඩංගු තන්තුවකි:

    • 1 = පණිවිඩය ගැන කිසිවක් නොදනී (msg_id ඉතා අඩුයි, අනෙක් පාර්ශවයට එය අමතක වී තිබිය හැක)
    • 2 = පණිවිඩයක් ලැබී නැත (msg_id ගබඩා කර ඇති හඳුනාගැනීම් පරාසය තුළට වැටේ; කෙසේ වෙතත්, අනෙක් පාර්ශ්වයට එවැනි පණිවිඩයක් නිසැකවම ලැබී නැත)
    • 3 = පණිවිඩය ලැබී නැත (msg_id ඉතා ඉහළ ය; කෙසේ වෙතත්, අනෙක් පාර්ශ්වයට නිසැකවම එය ලැබී නැත)
    • 4 = ලැබුණු පණිවිඩය (මෙම ප්‍රතිචාරය ඒ සමගම රිසිට්පතක් බව සලකන්න)
    • +8 = පණිවිඩය දැනටමත් පිළිගෙන ඇත
    • +16 = පණිවිඩය පිළිගැනීමක් අවශ්‍ය නොවේ
    • +32 = RPC විමසුම සැකසෙමින් පවතින හෝ දැනටමත් සම්පූර්ණ කර ඇති පණිවිඩයේ අඩංගු වේ
    • +64 = දැනටමත් ජනනය කර ඇති පණිවිඩයට අන්තර්ගතයට අදාළ ප්‍රතිචාරය
    • +128 = පණිවිඩය දැනටමත් ලැබී ඇති බව වෙනත් පාර්ශ්වයක් දනී
      මෙම ප්‍රතිචාරයට පිළිගැනීමක් අවශ්‍ය නොවේ. එය අදාළ msgs_state_req සහ එහිම පිළිගැනීමකි.
      අනෙක් පාර්ශ්වයට යවා ඇති බව පෙනෙන පණිවිඩයක් නොමැති බව හදිසියේම පෙනී ගියහොත්, පණිවිඩය යලි යැවිය හැකි බව සලකන්න. අනෙක් පාර්ශවයට පණිවිඩයේ පිටපත් දෙකක් එකවර ලැබිය යුතු වුවද, අනුපිටපත නොසලකා හරිනු ලැබේ. (වැඩි වේලාවක් ගත වී ඇත්නම් සහ මුල් msg_id තවදුරටත් වලංගු නොවේ නම්, පණිවිඩය msg_copy එකකින් එවිය යුතුය).
  • පණිවිඩවල තත්ත්වය ස්වේච්ඡාවෙන් සන්නිවේදනය කිරීම
    ඕනෑම පාර්ශ්වයකට අනෙක් පාර්ශවය විසින් සම්ප්‍රේෂණය කරන ලද පණිවිඩවල තත්ත්වය ස්වේච්ඡාවෙන් අනෙක් පාර්ශවයට දැනුම් දිය හැකිය.
    msgs_all_info#8cc0d131 msg_ids:Vector long info:string = MsgsAllInfo
  • එක් පණිවිඩයක තත්ත්වය පිළිබඳ දීර්ඝ ස්වේච්ඡා සන්නිවේදනය
    ...
    msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
    msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
  • පණිවිඩ නැවත යැවීමට පැහැදිලි ඉල්ලීම
    msg_resend_req#7d861a08 msg_ids:Vector long = MsgResendReq;
    ඉල්ලා සිටින පණිවිඩ නැවත යැවීමෙන් දුරස්ථ පාර්ශවය වහාම ප්‍රතිචාර දක්වයි […]
  • පිළිතුරු නැවත යැවීමට පැහැදිලි ඉල්ලීම
    msg_resend_ans_req#8610baeb msg_ids:Vector long = MsgResendReq;
    දුරස්ථ පාර්ශවය නැවත යැවීමෙන් වහාම ප්රතිචාර දක්වයි පිළිතුරු ඉල්ලූ පණිවිඩ වලට […]
  • පණිවිඩ පිටපත්
    සමහර අවස්ථා වලදී, තවදුරටත් වලංගු නොවන msg_id සහිත පැරණි පණිවිඩයක් නැවත යැවීමට අවශ්‍ය වේ. ඉන්පසු, එය පිටපත් කන්ටේනරයක ඔතා ඇත:
    msg_copy#e06046b2 orig_message:Message = MessageCopy;
    ලැබුණු පසු, පණිවිඩය එතුම නොතිබූ ආකාරයටම සකසනු ලැබේ. කෙසේ වෙතත්, orig_message.msg_id පණිවිඩය ලැබුණු බව නිශ්චිතවම දන්නේ නම්, නව පණිවිඩය සකසනු නොලැබේ (ඒ අතරම, එය සහ orig_message.msg_id පිළිගනු ලැබේ). orig_message.msg_id හි අගය බහාලුම් msg_id ට වඩා අඩු විය යුතුය.

කුමක් ගැන පවා අපි නිහඬව සිටිමු msgs_state_info නැවතත් නිම නොකළ TL හි කන් පිටතට ඇලී තිබේ (අපට බයිට් දෛශිකයක් අවශ්‍ය විය, පහළ බිටු දෙකේ enum එකක් තිබූ අතර ඉහළ බිටු දෙකේ කොඩි තිබුණි). කාරණය වෙනස් ය. මේ සියල්ල ප්‍රායෝගිකව පවතින්නේ මන්දැයි කිසිවෙකුට වැටහෙනවාද? සැබෑ ගනුදෙනුකරුවෙකු තුළ අවශ්‍යද?.. අමාරුවෙන්, නමුත් යම් පුද්ගලයෙක් නිදොස්කරණයේ යෙදී සිටින්නේ නම් සහ අන්තර්ක්‍රියාකාරී මාදිලියක නම්, කෙනෙකුට යම් ප්‍රයෝජනයක් ගැන සිතාගත හැකිය - කුමක් සහ කෙසේද යන්න සේවාදායකයෙන් අසන්න. නමුත් මෙහි ඉල්ලීම් විස්තර කර ඇත වට ගමන.

සෑම පාර්ශ්වයක්ම සංකේතනය කර පණිවිඩ යැවීම පමණක් නොව, තමන් ගැන, ඒවාට ප්‍රතිචාර ගැන, නොදන්නා කාලයක් සඳහා දත්ත ගබඩා කළ යුතු බව එයින් කියවේ. ප්‍රලේඛනය මෙම විශේෂාංගවල වේලාවන් හෝ ප්‍රායෝගික අදාළත්වය විස්තර නොකරයි. ක්රමයක් නැත. වඩාත්ම විශ්මය ජනක දෙය නම් ඒවා ඇත්ත වශයෙන්ම නිල ගනුදෙනුකරුවන්ගේ කේතයේ භාවිතා කිරීමයි! පෙනෙන විදිහට, පොදු ලියකියවිලිවලට ඇතුළත් නොකළ දෙයක් ඔවුන්ට පවසා ඇත. කේතයෙන් තේරුම් ගන්න ඇයි?, TL හි දී මෙන් තවදුරටත් සරල නොවේ - එය (සාපේක්ෂ වශයෙන්) තාර්කිකව හුදකලා කොටසක් නොවේ, නමුත් යෙදුම් ගෘහ නිර්මාණ ශිල්පයට බැඳී ඇති කෑල්ලක්, i.e. යෙදුම් කේතය තේරුම් ගැනීමට සැලකිය යුතු වැඩි කාලයක් අවශ්‍ය වනු ඇත.

පිං සහ වේලාවන්. පෝලිම්.

සෑම දෙයකින්ම, අපට සේවාදායක ගෘහ නිර්මාණ ශිල්පය (පසුපස හරහා ඉල්ලීම් බෙදා හැරීම) පිළිබඳ අනුමාන මතක නම්, තරමක් කණගාටුදායක දෙයක් අනුගමනය කරයි - TCP හි සියලුම බෙදා හැරීමේ සහතික තිබියදීත් (දත්ත ලබා දෙනු ලැබේ, නැතහොත් පරතරය ගැන ඔබට දන්වනු ලැබේ, නමුත් ගැටළුව ඇතිවීමට පෙර දත්ත ලබා දෙනු ඇත), MTProto තුළම තහවුරු කිරීම් - සහතික නැත. සේවාදායකයට ඔබගේ පණිවිඩය පහසුවෙන් නැති කර ගැනීමට හෝ ඉවත දැමිය හැකි අතර, ඒ ගැන කිසිවක් කළ නොහැක, විවිධ වර්ගයේ කිහිලිකරු භාවිතා කරන්න.

සහ පළමුවෙන්ම - පණිවිඩ පෝලිම්. හොඳයි, එක් දෙයක් සමඟ ආරම්භයේ සිටම සෑම දෙයක්ම පැහැදිලිව පෙනෙන්නට තිබුණි - තහවුරු නොකළ පණිවිඩයක් ගබඩා කර නැවත යැවිය යුතුය. සහ කුමන වේලාවෙන් පසුවද? ඒ වගේම විහිළුකාරයා ඔහුව දන්නවා. සමහර විට එම ඇබ්බැහි වූ සේවා පණිවිඩ කිහිලිකරු සමඟ මෙම ගැටළුව විසඳයි, කියන්න, ටෙලිග්‍රාම් ඩෙස්ක්ටොප් එකේ ඒවාට අනුරූප පෝලිම් 4 ක් පමණ ඇත (සමහර විට, දැනටමත් සඳහන් කර ඇති පරිදි, මේ සඳහා ඔබ එහි කේතය සහ ගෘහ නිර්මාණ ශිල්පය වඩාත් බැරෑරුම් ලෙස සොයා බැලිය යුතුය; ඒ සමඟම. කාලය, අපි එය නියැදියක් ලෙස ගත නොහැකි බව අපි දනිමු; MTProto යෝජනා ක්රමයෙන් නිශ්චිත වර්ග ගණනාවක් එහි භාවිතා නොවේ).

ඇයි මෙහෙම වෙන්නේ? බොහෝ විට, සේවාදායක ක්‍රමලේඛකයින්ට පොකුර තුළ විශ්වසනීයත්වය සහතික කිරීමට හෝ ඉදිරිපස සමතුලිතතාවයේ බෆරින් කිරීමට නොහැකි වූ අතර මෙම ගැටළුව සේවාදායකයා වෙත මාරු කර ඇත. බලාපොරොත්තු සුන්වීමෙන්, Vasily විකල්ප විකල්පයක් ක්‍රියාත්මක කිරීමට උත්සාහ කළේය, පෝලිම් දෙකක් පමණක්, TCP වෙතින් ඇල්ගොරිතම භාවිතා කරමින් - RTT සේවාදායකයට මැනීම සහ තහවුරු නොකළ ඉල්ලීම් ගණන අනුව “කවුළුව” (පණිවිඩවල) ප්‍රමාණය සකස් කිරීම. එනම්, සේවාදායකයේ භාරය තක්සේරු කිරීම සඳහා එවැනි රළු හූරිස්ටික් යනු අපගේ ඉල්ලීම් කීයක් එකවර හපන්න පුළුවන්ද නැති කර ගත හැකිද යන්නයි.

හොඳයි, එනම්, ඔබට තේරෙනවා, හරිද? ඔබට TCP හරහා ක්‍රියාත්මක වන ප්‍රොටෝකෝලයක් මත නැවත TCP ක්‍රියාත්මක කිරීමට සිදුවුවහොත්, මෙය ඉතා දුර්වල ලෙස නිර්මාණය කර ඇති ප්‍රොටෝකෝලයක් පෙන්නුම් කරයි.

ඔහ් ඔව්, ඔබට පෝලිම් එකකට වඩා අවශ්‍ය වන්නේ ඇයි, සහ කෙසේ වෙතත් ඉහළ මට්ටමේ API සමඟ වැඩ කරන පුද්ගලයෙකුට මෙයින් අදහස් කරන්නේ කුමක්ද? බලන්න, ඔබ ඉල්ලීමක් කරයි, එය අනුක්‍රමික කරයි, නමුත් බොහෝ විට ඔබට එය වහාම යැවිය නොහැක. ඇයි? මන්ද පිළිතුර වනු ඇත msg_id, තාවකාලික වනаමම ලේබලයක් වන අතර, එහි පැවරුම හැකි තරම් ප්‍රමාද වන තෙක් කල් දැමීම වඩාත් සුදුසුය - අප සහ ඔහු අතර ඇති කාලය නොගැලපීම හේතුවෙන් සේවාදායකය එය ප්‍රතික්ෂේප කළහොත් (ඇත්ත වශයෙන්ම, අපට අපගේ කාලය වර්තමානයෙන් මාරු කරන කිහිලිකරුවක් සෑදිය හැකිය. සේවාදායකයේ ප්‍රතිචාර වලින් ගණනය කරන ලද ඩෙල්ටාවක් එකතු කිරීමෙන් සේවාදායකයට - නිල සේවාදායකයින් මෙය කරයි, නමුත් එය බෆරින් කිරීම නිසා අමු සහ සාවද්‍ය වේ). එබැවින්, ඔබ පුස්තකාලයෙන් දේශීය ක්‍රියාකාරී ඇමතුමක් සමඟ ඉල්ලීමක් කරන විට, පණිවිඩය පහත අදියර හරහා යයි:

  1. එය එක් පෝලිමක පිහිටා ඇති අතර සංකේතනය කිරීමට බලා සිටී.
  2. පත් කළා msg_id සහ පණිවිඩය වෙනත් පෝලිමකට ගියේය - හැකි යොමු කිරීම; සොකට් වෙත යවන්න.
  3. අ) සේවාදායකය MsgsAck ප්‍රතිචාර දැක්වීය - පණිවිඩය භාර දෙන ලදී, අපි එය "අනෙකුත් පෝලිමෙන්" මකා දමමු.
    ආ) නැතහොත් අනෙක් අතට, ඔහු යම් දෙයකට කැමති නැත, ඔහු බැඩ්මස්ට පිළිතුරු දුන්නේය - "වෙනත් පෝලිමකින්" නැවත යවන්න
    ඇ) කිසිවක් දන්නේ නැත, පණිවිඩය වෙනත් පෝලිමකින් යලි යැවිය යුතුය - නමුත් එය හරියටම කවදාදැයි නොදනී.
  4. සේවාදායකය අවසානයේ ප්‍රතිචාර දැක්වීය RpcResult - සත්‍ය ප්‍රතිචාරය (හෝ දෝෂය) - ලබා දීම පමණක් නොව, සකසන ලදී.

සමහර විට, බහාලුම් භාවිතය අර්ධ වශයෙන් ගැටළුව විසඳා ගත හැකිය. මෙය පණිවිඩ පොකුරක් එකකට අසුරා ඇති අතර, සේවාදායකයා ඒ සියල්ලටම එකවර, එකකින් තහවුරු කරමින් ප්‍රතිචාර දැක්වූයේය. msg_id. නමුත් යම්කිසි වැරැද්දක් සිදුවුවහොත් ඔහු මෙම ඇසුරුම සම්පූර්ණයෙන්ම ප්‍රතික්ෂේප කරනු ඇත.

තවද මෙම අවස්ථාවේදී තාක්ෂණික නොවන සලකා බැලීම් ක්රියාත්මක වේ. අත්දැකීම් වලින්, අපි බොහෝ අත්වාරු දැක ඇති අතර, ඊට අමතරව, අපි දැන් නරක උපදෙස් සහ ගෘහ නිර්මාණ ශිල්පය පිළිබඳ තවත් උදාහරණ දකිනු ඇත - එවැනි තත්වයන් තුළ, විශ්වාස කිරීම සහ එවැනි තීරණ ගැනීම වටී ද? ප්රශ්නය වාචාලය (ඇත්ත වශයෙන්ම නොවේ).

අපි කතා කරන්නේ කුමක් ගැනද? “පණිවිඩ පිළිබඳ මත්ද්‍රව්‍ය පණිවිඩ” යන මාතෘකාව මත ඔබට තවමත් “ඔබ මෝඩයි, ඔබට අපගේ දීප්තිමත් සැලැස්ම තේරුණේ නැත!” වැනි විරෝධතා සමඟ අනුමාන කළ හැකිය. (එබැවින් සාමාන්‍ය පුද්ගලයින්ට අවශ්‍ය පරිදි, ප්‍රථමයෙන් ලේඛන ලියන්න, තාර්කිකත්වය සහ පැකට් හුවමාරුව පිළිබඳ උදාහරණ සමඟ, පසුව අපි කතා කරමු), එවිට වේලාවන්/කාලසීමාවන් යනු තනිකරම ප්‍රායෝගික සහ නිශ්චිත ප්‍රශ්නයකි, මෙහි ඇති සියල්ල දිගු කලක් තිස්සේ දන්නා කරුණකි. කල් ඉකුත්වීම් ගැන ලියකියවිලි අපට පවසන්නේ කුමක්ද?

සේවාදායකයක් සාමාන්‍යයෙන් RPC ප්‍රතිචාරයක් භාවිතා කරමින් සේවාදායකයෙකුගෙන් (සාමාන්‍යයෙන්, RPC විමසුමක්) පණිවිඩයක් ලැබීම පිළිගනී. ප්‍රතිචාරයක් දිගු කලක් පැමිණේ නම්, සේවාදායකයක් පළමුව කුවිතාන්සියක් එවිය හැකි අතර තරමක් පසුව, RPC ප්‍රතිචාරයම එවිය හැක.

සේවාදායකයෙකු සාමාන්‍යයෙන් සේවාදායකයකින් පණිවිඩයක් ලැබුණු බව (සාමාන්‍යයෙන්, RPC ප්‍රතිචාරයක්) පිළිගනී, එය ප්‍රමාද වී සම්ප්‍රේෂණය නොකළහොත් (එය උත්පාදනය වී ඇත්නම්, රිසිට්පතෙන් තත්පර 60-120 කින් තත්පර 16-XNUMXකින් පසුව) ඊළඟ RPC විමසුමට පිළිගැනීමක් එක් කරයි. සේවාදායකයෙන් පණිවිඩයක්). කෙසේ වෙතත්, දිගු කාලයක් සඳහා සේවාදායකය වෙත පණිවිඩ යැවීමට හේතුවක් නොමැති නම් හෝ සේවාදායකයෙන් (කියන්න, XNUMX ට වැඩි) නොපිළිගත් පණිවිඩ විශාල සංඛ්යාවක් තිබේ නම්, සේවාලාභියා ස්වාධීනව පිළිගැනීමක් සම්ප්රේෂණය කරයි.

... මම පරිවර්ථනය කරමි: අපට එය කොපමණ සහ කෙසේ අවශ්‍ය දැයි අපිම නොදනිමු, එබැවින් එය මෙසේ වීමට ඉඩ හරින්නැයි උපකල්පනය කරමු.

සහ පිං ගැන:

Ping පණිවිඩ (PING/PONG)

ping#7abe77ec ping_id:long = Pong;

ප්‍රතිචාරයක් සාමාන්‍යයෙන් එකම සම්බන්ධතාවයට ආපසු යවනු ලැබේ:

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

මෙම පණිවිඩ සඳහා පිළිගැනීම් අවශ්‍ය නොවේ. පොන්ග් එකක් සම්ප්‍රේෂණය වන්නේ පිං එකකට ප්‍රතිචාරයක් ලෙස පමණක් වන අතර පිං එකක් දෙපැත්තකින් ආරම්භ කළ හැකිය.

කල් දැමූ සම්බන්ධතා වසා දැමීම + PING

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

ping වගේ වැඩ. මීට අමතරව, මෙය ලැබුණු පසු, සේවාදායකය විසින් ටයිමරයක් ආරම්භ කරන අතර එමඟින් පෙර පැවති සියලුම ටයිමර ස්වයංක්‍රීයව නැවත සකසන එකම ආකාරයේ නව පණිවිඩයක් ලැබෙන්නේ නම් මිස තත්පර කිහිපයකට පසුව විසන්ධි_ප්‍රමාදය වත්මන් සම්බන්ධතාවය වසා දමයි. සේවාදායකයා සෑම තත්පර 60 කට වරක් මෙම පිං යවන්නේ නම්, උදාහරණයක් ලෙස, එය තත්පර 75 ට සමාන disconnect_delay සැකසිය හැක.

ඔයාට පිස්සු ද?! තත්පර 60 කින්, දුම්රිය ස්ථානයට ඇතුළු වී, මගීන් අතහැර දමා, උමග තුළ නැවත සම්බන්ධතා නැති වේ. තත්පර 120 කින්, ඔබට එය ඇසෙන අතරතුර, එය තවත් එකකට පැමිණෙන අතර, සම්බන්ධතාවය බොහෝ විට බිඳී යනු ඇත. හොඳයි, කකුල් එන්නේ කොතැනින්ද යන්න පැහැදිලිය - "මට නාදයක් ඇසුණා, නමුත් එය කොහේදැයි මම නොදනිමි", අන්තර්ක්‍රියාකාරී වැඩ සඳහා අදහස් කරන Nagl ගේ ඇල්ගොරිතම සහ TCP_NODELAY විකල්පය ඇත. නමුත්, සමාවෙන්න, එහි පෙරනිමි අගය - 200 තබා ගන්න මිලිතත්පර ඔබට සැබවින්ම සමාන දෙයක් නිරූපණය කිරීමට සහ හැකි පැකට් කිහිපයක සුරැකීමට අවශ්‍ය නම්, එය තත්පර 5කට කල් දමන්න, නැතහොත් "පරිශීලක ටයිප් කරමින් සිටී..." පණිවිඩයේ කල් ඉකුත්වීම දැන් වේ. නමුත් තවත් නැත.

අවසාන වශයෙන්, පිං. එනම්, TCP සම්බන්ධතාවයේ සජීවී බව පරීක්ෂා කිරීමයි. එය හාස්‍යජනකයි, නමුත් මීට වසර 10 කට පමණ පෙර මම අපගේ පීඨයේ නේවාසිකාගාරයේ පණිවිඩකරු ගැන විවේචනාත්මක පෙළක් ලිවීය - එහි කතුවරුන් සේවාදායකයාගෙන් සේවාදායකයාට පිං කර ඇත, නමුත් අනෙක් අතට නොවේ. නමුත් 3 වසර සිසුන් එක් දෙයක්, ජාත්‍යන්තර කාර්යාලයක් තවත් එකක් නේද?..

පළමුව, කුඩා අධ්යාපනික වැඩසටහනක්. TCP සම්බන්ධතාවයක්, පැකට් හුවමාරුවක් නොමැති විට, සති ගණනක් ජීවත් විය හැක. අරමුණ අනුව මෙය හොඳ නරක දෙකම වේ. ඔබ සේවාදායකයට SSH සම්බන්ධතාවයක් විවෘත කර ඇත්නම් එය හොඳයි, ඔබ පරිගණකයෙන් නැඟිට, රවුටරය නැවත ආරම්භ කර, ඔබේ ස්ථානයට ආපසු ගියේය - මෙම සේවාදායකය හරහා සැසිය ඉරා දමා නැත (ඔබ කිසිවක් ටයිප් කළේ නැත, පැකට් නොතිබුණි) , එය පහසුයි. සේවාදායකයේ සේවාදායකයින් දහස් ගණනක් සිටී නම්, එක් එක් සම්පත් ලබා ගැනීම නරක ය (ආයුබෝවන්, Postgres!), සහ සේවාලාභියාගේ ධාරකය බොහෝ කලකට පෙර නැවත ආරම්භ කර තිබිය හැකිය - නමුත් අපි ඒ ගැන නොදනිමු.

චැට්/අයිඑම් පද්ධති එක් අමතර හේතුවක් නිසා දෙවන අවස්ථාවට වැටේ - සබැඳි තත්ව. පරිශීලකයා "වැටී" නම්, ඔබ මේ පිළිබඳව ඔහුගේ මැදිහත්කරුවන්ට දැනුම් දිය යුතුය. එසේ නොමැතිනම්, ජබ්බර්ගේ නිර්මාතෘවරුන් විසින් සිදු කරන ලද (සහ වසර 20 ක් තිස්සේ නිවැරදි කරන ලද) වැරැද්දකින් ඔබ අවසන් වනු ඇත - පරිශීලකයා විසන්ධි වී ඇත, නමුත් ඔහු සබැඳි බව විශ්වාස කරමින් ඔවුන් ඔහුට දිගටම පණිවිඩ ලියයි (ඒවා ද මේවායින් සම්පූර්ණයෙන්ම නැති වී ඇත. විසන්ධි වීම සොයා ගැනීමට මිනිත්තු කිහිපයකට පෙර). නැත, TCP ටයිමර් ක්‍රියා කරන ආකාරය නොතේරෙන බොහෝ අය අහඹු ලෙස විසි කරන TCP_KEEPALIVE විකල්පය (තත්පර දස වැනි වල් අගයන් සැකසීමෙන්) මෙහි උදව් නොවනු ඇත - ඔබ OS කර්නලය පමණක් නොවන බවට වග බලා ගත යුතුය. පරිශීලකයාගේ යන්ත්‍රය ජීවමානව ඇත, නමුත් සාමාන්‍යයෙන් ක්‍රියා කරයි, ප්‍රතිචාර දැක්වීමට හැකියාව ඇත, සහ යෙදුමම (ඔබ සිතන්නේ එය කැටි කළ නොහැකිද? උබුන්ටු 18.04 හි ටෙලිග්‍රාම් ඩෙස්ක්ටොප් එක මට එක් වරකට වඩා කැටි විය).

ඒකයි ping කරන්න වෙන්නේ සේවාදායකය සේවාදායකයා, සහ අනෙක් අතට නොවේ - සේවාදායකයා මෙය කරන්නේ නම්, සම්බන්ධතාවය කැඩී ඇත්නම්, පිං ලබා නොදෙනු ඇත, ඉලක්කය සපුරා නොගනු ඇත.

අපි Telegram හි දකින්නේ කුමක්ද? එය හරියටම ප්රතිවිරුද්ධයයි! හොඳයි, එනම්. විධිමත් ලෙස, ඇත්ත වශයෙන්ම, දෙපැත්තටම එකිනෙකාට ping කළ හැකිය. ප්රායෝගිකව, ගනුදෙනුකරුවන් කිහිලිකරු භාවිතා කරයි ping_delay_disconnect, එය සේවාදායකයේ ටයිමරය සකසයි. හොඳයි, සමාවෙන්න, සේවාදායකයාට පිං නොමැතිව කොපමණ කාලයක් එහි ජීවත් වීමට අවශ්‍යද යන්න තීරණය කිරීම නොවේ. සේවාදායකය, එහි භාරය මත පදනම්ව, වඩා හොඳින් දනී. නමුත්, ඇත්ත වශයෙන්ම, ඔබ සම්පත් ගණන් නොගන්නේ නම්, ඔබ ඔබේම නපුරු පිනොචියෝ වනු ඇත, සහ කිහිලිකරුවෙක් කරනු ඇත ...

එය නිර්මාණය කළ යුතුව තිබුණේ කෙසේද?

Telegram/VKontakte කණ්ඩායම ප්‍රවාහන ක්ෂේත්‍රයේ (සහ පහළ) මට්ටමේ පරිගණක ජාල සහ අදාළ කාරණා සම්බන්ධයෙන් ඔවුන්ගේ අඩු සුදුසුකම් සම්බන්ධයෙන් එතරම් දක්ෂ නොවන බව ඉහත කරුණු පැහැදිලිව පෙන්නුම් කරන බව මම විශ්වාස කරමි.

එය මෙතරම් සංකීර්ණ වූයේ ඇයි, සහ ටෙලිග්‍රාම් ගෘහ නිර්මාණ ශිල්පීන් විරුද්ධ වීමට උත්සාහ කරන්නේ කෙසේද? ඔවුන් TCP සම්බන්ධතාවයෙන් බේරෙන සැසියක් සෑදීමට උත්සාහ කළ කාරණය කැඩී යයි, එනම්, දැන් ලබා නොදුන් දේ, අපි පසුව ලබා දෙන්නෙමු. ඔවුන් බොහෝ විට UDP ප්‍රවාහනයක් කිරීමට උත්සාහ කළ නමුත් ඔවුන් දුෂ්කරතාවන්ට මුහුණ දී එය අතහැර දමා ඇත (ලේඛන හිස් වන්නේ එබැවිනි - පුරසාරම් දෙඩීමට කිසිවක් නැත). නමුත් පොදුවේ ජාල සහ විශේෂයෙන් TCP ක්‍රියා කරන ආකාරය පිළිබඳ අවබෝධයක් නොමැතිකම හේතුවෙන්, ඔබට එය මත විශ්වාසය තැබිය හැක්කේ කොතැනද, සහ එය ඔබම කළ යුත්තේ කොතැනද (සහ කෙසේද), සහ මෙය ගුප්තකේතනය සමඟ ඒකාබද්ධ කිරීමට උත්සාහ කිරීම “කුරුල්ලන් දෙදෙනෙකු සමඟ එක ගලක්”, මේ එහි ප්‍රතිඵලයයි.

එය අවශ්ය වූයේ කෙසේද? යන කාරණය පදනම් කරගෙනය msg_id නැවත ධාවනය ප්‍රහාර වැළැක්වීම සඳහා ගුප්ත ලේඛන දෘෂ්ටි කෝණයකින් අවශ්‍ය වේලා මුද්‍රාවකි, එයට අනන්‍ය හඳුනාගැනීමේ ශ්‍රිතයක් ඇමිණීම වරදකි. එබැවින්, වර්තමාන ගෘහනිර්මාණ ශිල්පය මූලික වශයෙන් වෙනස් නොකර (යාවත්කාලීන ප්‍රවාහය උත්පාදනය කරන විට, එය මෙම පළ කිරීම් මාලාවේ තවත් කොටසක් සඳහා ඉහළ මට්ටමේ API මාතෘකාවකි), කෙනෙකුට අවශ්‍ය වනු ඇත:

  1. සේවාලාභියා වෙත TCP සම්බන්ධතාව තබාගෙන සිටින සේවාදායකය වගකීම දරයි - එය සොකට් එකෙන් කියවා ඇත්නම්, කරුණාකර දෝෂයක් පිළිගන්න, ක්‍රියාවට නංවන්න හෝ ආපසු දෙන්න, පාඩුවක් සිදු නොවේ. එවිට තහවුරු කිරීම id වල දෛශිකයක් නොවේ, නමුත් සරලව "අවසන් ලැබුණු seq_no" - TCP හි මෙන් අංකයක් (අංක දෙකක් - ඔබේ අනුක්‍රමය සහ තහවුරු කළ එක). අපි සෑම විටම සැසිය තුළ සිටිමු, එසේ නොවේ ද?
  2. නැවත ධාවනය වන ප්‍රහාර වැලැක්වීමේ වේලා මුද්‍රාව වෙනම ක්ෂේත්‍රයක්, la nonce එකක් බවට පත් වේ. එය පරීක්ෂා කර ඇත, නමුත් වෙනත් කිසිවක් බලපාන්නේ නැත. ප්රමාණවත් සහ uint32 - අපගේ ලුණු අවම වශයෙන් සෑම දින භාගයක්ම වෙනස් වුවහොත්, අපට වත්මන් වේලාවේ පූර්ණ සංඛ්‍යා කොටසක අඩු-ඇණවුම් බිටු වෙත බිටු 16 ක් වෙන් කළ හැකිය, ඉතිරිය - තත්පරයක භාගික කොටසකට (දැන් මෙන්).
  3. ඉවත් කරන ලදී msg_id කිසිසේත් - පසුපෙළ මත ඉල්ලීම් වෙන්කර හඳුනා ගැනීමේ දෘෂ්ටි කෝණයෙන්, පළමුව, සේවාදායක හැඳුනුම්පත ඇත, සහ දෙවනුව, සැසි හැඳුනුම්පත, ඒවා ඒකාබද්ධ කරන්න. ඒ අනුව ඉල්ලීම් හඳුනාගැනීමක් ලෙස එක් දෙයක් පමණක් ප්‍රමාණවත් වේ seq_no.

මෙය වඩාත්ම සාර්ථක විකල්පය ද නොවේ; සම්පූර්ණ අහඹු ලෙස හඳුනාගැනීමක් ලෙස සේවය කළ හැකිය - පණිවිඩයක් යැවීමේදී මෙය දැනටමත් ඉහළ මට්ටමේ API තුළ සිදු කර ඇත. ගෘහ නිර්මාණ ශිල්පය සාපේක්ෂ සිට නිරපේක්ෂ දක්වා සම්පූර්ණයෙන්ම ප්‍රතිනිර්මාණය කිරීම වඩා හොඳය, නමුත් මෙය තවත් කොටසකට මාතෘකාවකි, මෙම සටහන නොවේ.

API?

Ta-daam! ඉතින්, වේදනාවෙන් සහ අත්වාරුවලින් පිරුණු මාවතක් හරහා අරගල කළ අපට අවසානයේ සේවාදායකයට ඕනෑම ඉල්ලීමක් යැවීමට සහ ඒවාට පිළිතුරු ලබා ගැනීමට මෙන්ම සේවාදායකයෙන් යාවත්කාලීන කිරීම් ලබා ගැනීමට හැකි විය (ඉල්ලීමකට ප්‍රතිචාරයක් ලෙස නොව, එයම PUSH වැනි, යමෙකුට එය වඩාත් පැහැදිලි නම් අප වෙත එවයි).

අවධානය, දැන් ලිපියේ Perl හි ඇති එකම උදාහරණය වනු ඇත! (වාක්‍ය ඛණ්ඩය ගැන නොදන්නා අය සඳහා, bless හි පළමු තර්කය වස්තුවේ දත්ත ව්‍යුහය වේ, දෙවැන්න එහි පන්තියයි):

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 හි සාමාන්‍ය Web API එකක දත්ත ව්‍යුහය විය හැකිය, පන්ති ද වස්තු වලට අමුණා තිබේද?..

ඉතින් මේක වෙන්නේ මෙහෙමයි... සහෝදරවරුනි, ඒ සියල්ල ගැන කුමක් කිව හැකිද?.. මෙතරම් උත්සාහයක් - අපි වෙබ් ක්‍රමලේඛකයින් සිටින තැන විවේක ගැනීමට නැවතුනෙමු. පටන් ගන්නවා විතරයි?.. HTTPS හරහා JSON පමණක් සරල නොවේද?! අපට හුවමාරුව ලැබුණේ කුමක්ද? උත්සාහය වටිනවාද?

TL+MTPproto අපට ලබා දුන්නේ කුමක්ද සහ හැකි විකල්ප මොනවාදැයි අපි තක්සේරු කරමු. හොඳයි, ඉල්ලීම්-ප්‍රතිචාර ආකෘතිය කෙරෙහි අවධානය යොමු කරන HTTP, නරක සුදුසුකමක්, නමුත් අඩුම තරමින් TLS මත යමක් තිබේද?

සංයුක්ත අනුක්‍රමිකකරණය. JSON වලට සමාන මෙම දත්ත ව්‍යුහය දුටු විට එහි ද්විමය අනුවාද ඇති බව මට මතකය. MsgPack ප්‍රමාණවත් ලෙස විස්තාරණය කළ නොහැකි ලෙස සලකුණු කරමු, නමුත් උදාහරණයක් ලෙස, CBOR - මාර්ගයෙන්, විස්තර කර ඇති ප්‍රමිතියක් ඇත. RFC 7049. එය නිර්වචනය කරන කාරනය සඳහා එය කැපී පෙනේ ටැග්, පුළුල් කිරීමේ යාන්ත්රණයක් ලෙස, සහ අතර දැනටමත් සම්මත කර ඇත ඇත:

  • 25 + 256 - නැවත නැවත රේඛා වෙනුවට රේඛා අංකයට යොමු කිරීම, එවැනි ලාභ සම්පීඩන ක්‍රමයක්
  • 26 - පන්තියේ නම සහ කන්ස්ට්‍රක්ටර් තර්ක සහිත අනුක්‍රමික Perl වස්තුව
  • 27 - වර්ග නාමය සහ කන්ස්ට්‍රක්ටර් තර්ක සහිත අනුක්‍රමික භාෂාවෙන් ස්වාධීන වස්තුවකි

හොඳයි, මම TL සහ CBOR හි තන්තු සහ වස්තු ඇසුරුම් සක්‍රීය කර ඇති එකම දත්ත අනුක්‍රමික කිරීමට උත්සාහ කළෙමි. ප්‍රතිඵලය මෙගාබයිට් එකකින් කොතැනක හෝ CBOR ට පක්ෂව වෙනස් වීමට පටන් ගත්තේය.

cborlen=1039673 tl_len=1095092

එසේ නම්, නිගමනය විය: සංසන්දනාත්මක කාර්යක්ෂමතාවයක් සහිත සමමුහුර්ත කිරීමේ අසාර්ථකත්වය හෝ නොදන්නා හඳුනාගැනීමේ ගැටලුවට යටත් නොවන සැලකිය යුතු ලෙස සරල ආකෘති ඇත.

වේගවත් සම්බන්ධතා ස්ථාපනය. මෙයින් අදහස් කරන්නේ නැවත සම්බන්ධ කිරීමෙන් පසු ශුන්‍ය RTT (යතුර දැනටමත් එක් වරක් ජනනය කර ඇති විට) - පළමු MTPproto පණිවිඩයෙන් අදාළ වේ, නමුත් සමහර වෙන් කිරීම් සමඟ - එකම ලුණු පහර, සැසිය කුණු වී නැත, ආදිය. ඒ වෙනුවට TLS අපට පිරිනමන්නේ කුමක්ද? මාතෘකාව පිළිබඳ උපුටා දැක්වීම:

TLS හි PFS භාවිතා කරන විට, TLS සැසි ටිකට් (RFC 5077) යතුරු නැවත සාකච්ඡා නොකර සහ සේවාදායකයේ ප්‍රධාන තොරතුරු ගබඩා නොකර සංකේතාත්මක සැසියක් නැවත ආරම්භ කිරීමට. පළමු සම්බන්ධතාවය විවෘත කර යතුරු නිර්මාණය කරන විට, සේවාදායකය සම්බන්ධතා තත්ත්වය සංකේතනය කර එය සේවාදායකයා වෙත සම්ප්‍රේෂණය කරයි (සැසි ටිකට් ආකාරයෙන්). ඒ අනුව, සම්බන්ධතාවය නැවත ආරම්භ වූ විට, සේවාදායකයා විසින් සැසි යතුර ඇතුළුව සැසි ටිකට් පතක් නැවත සේවාදායකය වෙත යවයි. ප්‍රවේශ පත්‍රයම තාවකාලික යතුරකින් (සැසි ටිකට් යතුර) සංකේතනය කර ඇති අතර එය සේවාදායකයේ ගබඩා කර ඇති අතර පොකුරු විසඳුම් තුළ SSL සකසන සියලුම ඉදිරිපස සේවාදායකයන් අතර බෙදා හැරිය යුතුය.[10]. මේ අනුව, සැසි ප්‍රවේශ පත්‍රයක් හඳුන්වා දීමෙන් තාවකාලික සේවාදායක යතුරු අවදානමට ලක්වුවහොත් PFS උල්ලංඝනය විය හැක, උදාහරණයක් ලෙස, ඒවා දිගු කාලයක් ගබඩා කර ඇති විට (OpenSSL, nginx, Apache වැඩසටහනේ මුළු කාලය සඳහාම ඒවා පෙරනිමියෙන් ගබඩා කරයි; ජනප්‍රිය අඩවි භාවිතා කරයි. යතුර පැය කිහිපයක්, දින දක්වා).

මෙහිදී RTT ශුන්‍ය නොවේ, ඔබ අවම වශයෙන් ClientHello සහ ServerHello හුවමාරු කර ගත යුතුය, ඉන්පසු සේවාදායකයාට Finished සමඟ දත්ත යැවිය හැක. නමුත් මෙහිදී අප මතක තබා ගත යුත්තේ අප සතුව අලුතින් විවෘත කරන ලද සම්බන්ධතා පොකුරක් සහිත වෙබය නොමැති බවත්, නමුත් පණිවිඩකරුවෙකු වන බවත්, එහි සම්බන්ධතාවය බොහෝ විට එකක් සහ වැඩි වශයෙන් හෝ අඩු කාලයක් පවතින, වෙබ් පිටු වෙත සාපේක්ෂව කෙටි ඉල්ලීම් - සියල්ල බහුකාර්ය වේ. අභ්යන්තරව. එනම්, අපට ඇත්තෙන්ම නරක උමං මාර්ග අංශයක් හමු නොවූයේ නම් එය බෙහෙවින් පිළිගත හැකි ය.

වෙන දෙයක් අමතකද? අදහස් වල ලියන්න.

ඉදිරියට පැවැත්වේ!

මෙම ලිපි මාලාවේ දෙවන කොටසේදී අපි තාක්ෂණික නොව ආයතනික ගැටළු සලකා බලමු - ප්‍රවේශයන්, දෘෂ්ටිවාදය, අතුරු මුහුණත, පරිශීලකයින් කෙරෙහි දක්වන ආකල්පය යනාදිය. කෙසේ වෙතත්, මෙහි ඉදිරිපත් කරන ලද තාක්ෂණික තොරතුරු මත පදනම්ව.

තෙවන කොටස තාක්ෂණික සංරචක / සංවර්ධන අත්දැකීම් විශ්ලේෂණය කිරීම දිගටම කරගෙන යනු ඇත. ඔබ ඉගෙන ගනු ඇත, විශේෂයෙන්:

  • විවිධ TL වර්ග සමඟ පැන්ඩෙමෝනියම් දිගටම කරගෙන යාම
  • නාලිකා සහ සුපිරි කණ්ඩායම් ගැන නොදන්නා දේවල්
  • ඇයි දෙබස් රෝස්ටර් වලට වඩා නරක
  • නිරපේක්ෂ එදිරිව සාපේක්ෂ පණිවිඩ ආමන්ත්‍රණය ගැන
  • ඡායාරූපය සහ රූපය අතර වෙනස කුමක්ද?
  • ඉමොජි ඇල අකුරු වලට බාධා කරන ආකාරය

සහ අනෙකුත් අත්වාරු! සුසරව සිටින්න!

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න