ಟೆಲಿಗ್ರಾಮ್‌ನ ಪ್ರೋಟೋಕಾಲ್ ಮತ್ತು ಸಾಂಸ್ಥಿಕ ವಿಧಾನಗಳ ಟೀಕೆ. ಭಾಗ 1, ತಾಂತ್ರಿಕ: ಮೊದಲಿನಿಂದ ಕ್ಲೈಂಟ್ ಬರೆಯುವ ಅನುಭವ - TL, MT

ಇತ್ತೀಚೆಗೆ, ಟೆಲಿಗ್ರಾಮ್ ಎಷ್ಟು ಉತ್ತಮವಾಗಿದೆ, ಡ್ಯುರೊವ್ ಸಹೋದರರು ನೆಟ್‌ವರ್ಕ್ ವ್ಯವಸ್ಥೆಗಳನ್ನು ನಿರ್ಮಿಸುವಲ್ಲಿ ಎಷ್ಟು ಅದ್ಭುತ ಮತ್ತು ಅನುಭವಿಯಾಗಿದ್ದಾರೆ ಎಂಬಿತ್ಯಾದಿ ಪೋಸ್ಟ್‌ಗಳು ಹಬ್ರೆಯಲ್ಲಿ ಹೆಚ್ಚಾಗಿ ಕಾಣಿಸಿಕೊಳ್ಳಲು ಪ್ರಾರಂಭಿಸಿವೆ. ಅದೇ ಸಮಯದಲ್ಲಿ, ಕೆಲವೇ ಜನರು ನಿಜವಾಗಿಯೂ ತಾಂತ್ರಿಕ ಸಾಧನದಲ್ಲಿ ತಮ್ಮನ್ನು ತಾವು ತೊಡಗಿಸಿಕೊಂಡಿದ್ದಾರೆ - ಹೆಚ್ಚೆಂದರೆ, ಅವರು JSON ಆಧರಿಸಿ ಸಾಕಷ್ಟು ಸರಳವಾದ (ಮತ್ತು MTProto ಗಿಂತ ಭಿನ್ನವಾದ) Bot API ಅನ್ನು ಬಳಸುತ್ತಾರೆ ಮತ್ತು ಸಾಮಾನ್ಯವಾಗಿ ಸ್ವೀಕರಿಸುತ್ತಾರೆ ನಂಬಿಕೆಯ ಮೇಲೆ ಸಂದೇಶವಾಹಕನ ಸುತ್ತ ಸುತ್ತುವ ಎಲ್ಲಾ ಹೊಗಳಿಕೆಗಳು ಮತ್ತು PR. ಸುಮಾರು ಒಂದೂವರೆ ವರ್ಷಗಳ ಹಿಂದೆ, Eshelon NGO ವಾಸಿಲಿಯಲ್ಲಿ ನನ್ನ ಸಹೋದ್ಯೋಗಿ (ದುರದೃಷ್ಟವಶಾತ್, ಡ್ರಾಫ್ಟ್‌ನೊಂದಿಗೆ ಹ್ಯಾಬ್ರೆ ಅವರ ಖಾತೆಯನ್ನು ಅಳಿಸಲಾಗಿದೆ) ಪರ್ಲ್‌ನಲ್ಲಿ ಮೊದಲಿನಿಂದಲೂ ತನ್ನದೇ ಆದ ಟೆಲಿಗ್ರಾಮ್ ಕ್ಲೈಂಟ್ ಅನ್ನು ಬರೆಯಲು ಪ್ರಾರಂಭಿಸಿದರು ಮತ್ತು ನಂತರ ಈ ಸಾಲುಗಳ ಲೇಖಕರು ಸೇರಿಕೊಂಡರು. ಏಕೆ ಪರ್ಲ್, ಕೆಲವರು ತಕ್ಷಣ ಕೇಳುತ್ತಾರೆ? ಏಕೆಂದರೆ ಅಂತಹ ಯೋಜನೆಗಳು ಈಗಾಗಲೇ ಇತರ ಭಾಷೆಗಳಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿವೆ.ವಾಸ್ತವವಾಗಿ, ಇದು ವಿಷಯವಲ್ಲ, ಯಾವುದೇ ಭಾಷೆ ಇಲ್ಲದಿರುವ ಬೇರೆ ಯಾವುದೇ ಭಾಷೆ ಇರಬಹುದು. ಸಿದ್ಧ ಗ್ರಂಥಾಲಯ, ಮತ್ತು ಅದರ ಪ್ರಕಾರ ಲೇಖಕರು ಎಲ್ಲಾ ರೀತಿಯಲ್ಲಿ ಹೋಗಬೇಕು ಮೊದಲಿನಿಂದ. ಇದಲ್ಲದೆ, ಗುಪ್ತ ಲಿಪಿ ಶಾಸ್ತ್ರವು ನಂಬಿಕೆಯ ವಿಷಯವಾಗಿದೆ, ಆದರೆ ಪರಿಶೀಲಿಸಿ. ಸುರಕ್ಷತೆಯ ಗುರಿಯನ್ನು ಹೊಂದಿರುವ ಉತ್ಪನ್ನದೊಂದಿಗೆ, ನೀವು ತಯಾರಕರಿಂದ ಸಿದ್ಧಪಡಿಸಿದ ಲೈಬ್ರರಿಯನ್ನು ಅವಲಂಬಿಸಲಾಗುವುದಿಲ್ಲ ಮತ್ತು ಅದನ್ನು ಕುರುಡಾಗಿ ನಂಬುವುದಿಲ್ಲ (ಆದಾಗ್ಯೂ, ಇದು ಎರಡನೇ ಭಾಗದ ವಿಷಯವಾಗಿದೆ). ಈ ಸಮಯದಲ್ಲಿ, ಲೈಬ್ರರಿಯು "ಸರಾಸರಿ" ಮಟ್ಟದಲ್ಲಿ ಉತ್ತಮವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ (ಯಾವುದೇ API ವಿನಂತಿಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ).

ಆದಾಗ್ಯೂ, ಈ ಪೋಸ್ಟ್‌ಗಳ ಸರಣಿಯಲ್ಲಿ ಹೆಚ್ಚಿನ ಕ್ರಿಪ್ಟೋಗ್ರಫಿ ಅಥವಾ ಗಣಿತ ಇರುವುದಿಲ್ಲ. ಆದರೆ ಅನೇಕ ಇತರ ತಾಂತ್ರಿಕ ವಿವರಗಳು ಮತ್ತು ವಾಸ್ತುಶಿಲ್ಪದ ಊರುಗೋಲುಗಳು ಇರುತ್ತವೆ (ಮೊದಲಿನಿಂದ ಬರೆಯದವರಿಗೆ ಸಹ ಉಪಯುಕ್ತವಾಗಿದೆ, ಆದರೆ ಯಾವುದೇ ಭಾಷೆಯಲ್ಲಿ ಗ್ರಂಥಾಲಯವನ್ನು ಬಳಸುತ್ತದೆ). ಆದ್ದರಿಂದ, ಕ್ಲೈಂಟ್ ಅನ್ನು ಮೊದಲಿನಿಂದಲೂ ಕಾರ್ಯಗತಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸುವುದು ಮುಖ್ಯ ಗುರಿಯಾಗಿದೆ ಅಧಿಕೃತ ದಾಖಲೆಗಳ ಪ್ರಕಾರ. ಅಂದರೆ, ಅಧಿಕೃತ ಕ್ಲೈಂಟ್‌ಗಳ ಮೂಲ ಕೋಡ್ ಮುಚ್ಚಲ್ಪಟ್ಟಿದೆ ಎಂದು ಭಾವಿಸೋಣ (ಮತ್ತೆ, ಎರಡನೇ ಭಾಗದಲ್ಲಿ ಇದು ನಿಜ ಎಂಬ ಅಂಶದ ವಿಷಯವನ್ನು ನಾವು ಹೆಚ್ಚು ವಿವರವಾಗಿ ಒಳಗೊಳ್ಳುತ್ತೇವೆ ಅದು ಸಂಭವಿಸುತ್ತದೆ ಆದ್ದರಿಂದ), ಆದರೆ, ಹಳೆಯ ದಿನಗಳಲ್ಲಿದ್ದಂತೆ, ಉದಾಹರಣೆಗೆ, RFC ಯಂತಹ ಮಾನದಂಡವಿದೆ - ನಿರ್ದಿಷ್ಟತೆಯ ಪ್ರಕಾರ ಕ್ಲೈಂಟ್ ಅನ್ನು ಬರೆಯಲು ಸಾಧ್ಯವೇ, ಮೂಲ ಕೋಡ್‌ನಲ್ಲಿ “ನೋಡದೆ”, ಅದು ಅಧಿಕೃತವಾಗಿರಲಿ (ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್, ಮೊಬೈಲ್), ಅಥವಾ ಅನಧಿಕೃತ ಟೆಲಿಥಾನ್?

ಪರಿವಿಡಿ:

ದಾಖಲೆ... ಇದು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ, ಸರಿ? ಅದು ನಿಜವೆ?..

ಈ ಲೇಖನದ ಟಿಪ್ಪಣಿಗಳ ತುಣುಕುಗಳನ್ನು ಕಳೆದ ಬೇಸಿಗೆಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಲು ಪ್ರಾರಂಭಿಸಿತು. ಅಧಿಕೃತ ವೆಬ್‌ಸೈಟ್‌ನಲ್ಲಿ ಈ ಸಮಯದಲ್ಲಿ https://core.telegram.org ದಸ್ತಾವೇಜನ್ನು ಲೇಯರ್ 23 ರಂತೆ, ಅಂದರೆ. 2014 ರಲ್ಲಿ ಎಲ್ಲೋ ಸಿಲುಕಿಕೊಂಡಿದೆ (ನೆನಪಿಡಿ, ಆಗ ಚಾನೆಲ್‌ಗಳೂ ಇರಲಿಲ್ಲವೇ?). ಸಹಜವಾಗಿ, ಸಿದ್ಧಾಂತದಲ್ಲಿ, ಇದು 2014 ರಲ್ಲಿ ಆ ಸಮಯದಲ್ಲಿ ಕ್ರಿಯಾತ್ಮಕತೆಯೊಂದಿಗೆ ಕ್ಲೈಂಟ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ನಮಗೆ ಅವಕಾಶ ನೀಡಿರಬೇಕು. ಆದರೆ ಈ ಸ್ಥಿತಿಯಲ್ಲಿಯೂ ಸಹ, ದಸ್ತಾವೇಜನ್ನು ಮೊದಲನೆಯದಾಗಿ, ಅಪೂರ್ಣವಾಗಿತ್ತು ಮತ್ತು ಎರಡನೆಯದಾಗಿ, ಸ್ಥಳಗಳಲ್ಲಿ ಅದು ಸ್ವತಃ ವಿರೋಧಿಸುತ್ತದೆ. ಕೇವಲ ಒಂದು ತಿಂಗಳ ಹಿಂದೆ, ಸೆಪ್ಟೆಂಬರ್ 2019 ರಲ್ಲಿ, ಅದು ಆಕಸ್ಮಿಕವಾಗಿ ಸಂಪೂರ್ಣವಾಗಿ ಇತ್ತೀಚಿನ ಲೇಯರ್ 105 ಗಾಗಿ ಸೈಟ್‌ನಲ್ಲಿ ದಾಖಲಾತಿಗಳ ದೊಡ್ಡ ನವೀಕರಣವಿದೆ ಎಂದು ಕಂಡುಹಿಡಿಯಲಾಯಿತು, ಈಗ ಎಲ್ಲವನ್ನೂ ಮತ್ತೆ ಓದಬೇಕಾಗಿದೆ ಎಂಬ ಟಿಪ್ಪಣಿಯೊಂದಿಗೆ. ವಾಸ್ತವವಾಗಿ, ಅನೇಕ ಲೇಖನಗಳನ್ನು ಪರಿಷ್ಕರಿಸಲಾಯಿತು, ಆದರೆ ಅನೇಕವು ಬದಲಾಗದೆ ಉಳಿದಿವೆ. ಆದ್ದರಿಂದ, ದಸ್ತಾವೇಜನ್ನು ಕುರಿತು ಕೆಳಗಿನ ಟೀಕೆಗಳನ್ನು ಓದುವಾಗ, ಈ ಕೆಲವು ವಿಷಯಗಳು ಇನ್ನು ಮುಂದೆ ಪ್ರಸ್ತುತವಲ್ಲ, ಆದರೆ ಕೆಲವು ಇನ್ನೂ ಸಾಕಷ್ಟು ಎಂದು ನೀವು ನೆನಪಿನಲ್ಲಿಟ್ಟುಕೊಳ್ಳಬೇಕು. ಎಲ್ಲಾ ನಂತರ, ಆಧುನಿಕ ಜಗತ್ತಿನಲ್ಲಿ 5 ವರ್ಷಗಳು ಕೇವಲ ದೀರ್ಘ ಸಮಯವಲ್ಲ, ಆದರೆ ತುಂಬಾ ಬಹಳಷ್ಟು. ಆ ಸಮಯದಿಂದ (ವಿಶೇಷವಾಗಿ ನೀವು ತಿರಸ್ಕರಿಸಿದ ಮತ್ತು ಪುನರುಜ್ಜೀವನಗೊಂಡ ಜಿಯೋಚಾಟ್ ಸೈಟ್‌ಗಳನ್ನು ಗಣನೆಗೆ ತೆಗೆದುಕೊಳ್ಳದಿದ್ದರೆ), ಸ್ಕೀಮ್‌ನಲ್ಲಿನ API ವಿಧಾನಗಳ ಸಂಖ್ಯೆಯು ನೂರರಿಂದ ಇನ್ನೂರ ಐವತ್ತಕ್ಕೂ ಹೆಚ್ಚಿದೆ!

ಯುವ ಲೇಖಕರಾಗಿ ಎಲ್ಲಿ ಪ್ರಾರಂಭಿಸಬೇಕು?

ನೀವು ಮೊದಲಿನಿಂದ ಬರೆಯುತ್ತೀರಾ ಅಥವಾ ಬಳಸುತ್ತೀರಾ ಎಂಬುದು ಅಪ್ರಸ್ತುತವಾಗುತ್ತದೆ, ಉದಾಹರಣೆಗೆ, ರೆಡಿಮೇಡ್ ಲೈಬ್ರರಿಗಳು ಹಾಗೆ ಪೈಥಾನ್‌ಗಾಗಿ ಟೆಲಿಥಾನ್ ಅಥವಾ PHP ಗಾಗಿ ಮೇಡ್‌ಲೈನ್, ಯಾವುದೇ ಸಂದರ್ಭದಲ್ಲಿ, ನಿಮಗೆ ಮೊದಲು ಅಗತ್ಯವಿರುತ್ತದೆ ನಿಮ್ಮ ಅರ್ಜಿಯನ್ನು ನೋಂದಾಯಿಸಿ - ನಿಯತಾಂಕಗಳನ್ನು ಪಡೆಯಿರಿ api_id и api_hash (VKontakte API ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಿದವರು ತಕ್ಷಣವೇ ಅರ್ಥಮಾಡಿಕೊಳ್ಳುತ್ತಾರೆ) ಅದರ ಮೂಲಕ ಸರ್ವರ್ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಗುರುತಿಸುತ್ತದೆ. ಈ ಮಾಡಬೇಕು ಕಾನೂನು ಕಾರಣಗಳಿಗಾಗಿ ಇದನ್ನು ಮಾಡಿ, ಆದರೆ ಲೈಬ್ರರಿ ಲೇಖಕರು ಅದನ್ನು ಎರಡನೇ ಭಾಗದಲ್ಲಿ ಏಕೆ ಪ್ರಕಟಿಸಬಾರದು ಎಂಬುದರ ಕುರಿತು ನಾವು ಹೆಚ್ಚು ಮಾತನಾಡುತ್ತೇವೆ. ಪರೀಕ್ಷಾ ಮೌಲ್ಯಗಳೊಂದಿಗೆ ನೀವು ತೃಪ್ತರಾಗಬಹುದು, ಆದರೂ ಅವು ಬಹಳ ಸೀಮಿತವಾಗಿವೆ - ಈಗ ನೀವು ನೋಂದಾಯಿಸಿಕೊಳ್ಳಬಹುದು ಎಂಬುದು ಸತ್ಯ ಒಂದೇ ಒಂದು ಅಪ್ಲಿಕೇಶನ್, ಆದ್ದರಿಂದ ಅದರೊಳಗೆ ತಲೆಕೆಡಿಸಿಕೊಳ್ಳಬೇಡಿ.

ಈಗ, ತಾಂತ್ರಿಕ ದೃಷ್ಟಿಕೋನದಿಂದ, ನೋಂದಣಿಯ ನಂತರ ನಾವು ದಸ್ತಾವೇಜನ್ನು, ಪ್ರೋಟೋಕಾಲ್ ಇತ್ಯಾದಿಗಳಿಗೆ ನವೀಕರಣಗಳ ಬಗ್ಗೆ ಟೆಲಿಗ್ರಾಮ್‌ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ಸ್ವೀಕರಿಸಬೇಕು ಎಂಬ ಅಂಶದಲ್ಲಿ ನಾವು ಆಸಕ್ತಿ ಹೊಂದಿರಬೇಕು. ಅಂದರೆ, ಡಾಕ್‌ಗಳೊಂದಿಗಿನ ಸೈಟ್ ಸರಳವಾಗಿ ಕೈಬಿಡಲ್ಪಟ್ಟಿದೆ ಮತ್ತು ಗ್ರಾಹಕರನ್ನು ಮಾಡಲು ಪ್ರಾರಂಭಿಸಿದವರೊಂದಿಗೆ ನಿರ್ದಿಷ್ಟವಾಗಿ ಕೆಲಸ ಮಾಡುವುದನ್ನು ಮುಂದುವರೆಸಿದೆ ಎಂದು ಒಬ್ಬರು ಊಹಿಸಬಹುದು, ಏಕೆಂದರೆ ಇದು ಸುಲಭವಾಗಿದೆ. ಆದರೆ ಇಲ್ಲ, ಅಂತಹ ಯಾವುದನ್ನೂ ಗಮನಿಸಿಲ್ಲ, ಯಾವುದೇ ಮಾಹಿತಿ ಬಂದಿಲ್ಲ.

ಮತ್ತು ನೀವು ಮೊದಲಿನಿಂದ ಬರೆಯುತ್ತಿದ್ದರೆ, ನಂತರ ಪಡೆದ ನಿಯತಾಂಕಗಳನ್ನು ಬಳಸುವುದು ಇನ್ನೂ ಬಹಳ ದೂರದಲ್ಲಿದೆ. ಆದರೂ https://core.telegram.org/ ಮತ್ತು ಮೊದಲಿಗೆ ಪ್ರಾರಂಭಿಸುವಿಕೆಯಲ್ಲಿ ಅವರ ಬಗ್ಗೆ ಮಾತನಾಡುತ್ತಾರೆ, ವಾಸ್ತವವಾಗಿ, ನೀವು ಮೊದಲು ಕಾರ್ಯಗತಗೊಳಿಸಬೇಕಾಗುತ್ತದೆ MTP ಪ್ರೋಟೋಕಾಲ್ - ಆದರೆ ನೀವು ನಂಬಿದರೆ OSI ಮಾದರಿಯ ಪ್ರಕಾರ ಲೇಔಟ್ ಪ್ರೋಟೋಕಾಲ್ನ ಸಾಮಾನ್ಯ ವಿವರಣೆಗಾಗಿ ಪುಟದ ಕೊನೆಯಲ್ಲಿ, ಅದು ಸಂಪೂರ್ಣವಾಗಿ ವ್ಯರ್ಥವಾಗಿದೆ.

ವಾಸ್ತವವಾಗಿ, MTProto ಮೊದಲು ಮತ್ತು ನಂತರ, ಏಕಕಾಲದಲ್ಲಿ ಹಲವಾರು ಹಂತಗಳಲ್ಲಿ (OS ಕರ್ನಲ್‌ನಲ್ಲಿ ಕೆಲಸ ಮಾಡುವ ವಿದೇಶಿ ನೆಟ್‌ವರ್ಕರ್‌ಗಳು ಹೇಳುವಂತೆ, ಲೇಯರ್ ಉಲ್ಲಂಘನೆ), ದೊಡ್ಡ, ನೋವಿನ ಮತ್ತು ಭಯಾನಕ ವಿಷಯವು ದಾರಿಯಲ್ಲಿ ಸಿಗುತ್ತದೆ...

ಬೈನರಿ ಧಾರಾವಾಹಿ: TL (ಟೈಪ್ ಲಾಂಗ್ವೇಜ್) ಮತ್ತು ಅದರ ಯೋಜನೆ, ಮತ್ತು ಪದರಗಳು, ಮತ್ತು ಅನೇಕ ಇತರ ಭಯಾನಕ ಪದಗಳು

ಈ ವಿಷಯವು ವಾಸ್ತವವಾಗಿ, ಟೆಲಿಗ್ರಾಮ್‌ನ ಸಮಸ್ಯೆಗಳಿಗೆ ಪ್ರಮುಖವಾಗಿದೆ. ಮತ್ತು ನೀವು ಅದನ್ನು ಪರಿಶೀಲಿಸಲು ಪ್ರಯತ್ನಿಸಿದರೆ ಬಹಳಷ್ಟು ಭಯಾನಕ ಪದಗಳು ಇರುತ್ತವೆ.

ಆದ್ದರಿಂದ, ರೇಖಾಚಿತ್ರ ಇಲ್ಲಿದೆ. ಈ ಮಾತು ನಿಮ್ಮ ಮನಸ್ಸಿಗೆ ಬಂದರೆ, ಹೇಳಿ JSON ಸ್ಕೀಮಾ, ನೀವು ಸರಿಯಾಗಿ ಯೋಚಿಸಿದ್ದೀರಿ. ಗುರಿಯು ಒಂದೇ ಆಗಿರುತ್ತದೆ: ಪ್ರಸಾರವಾದ ಡೇಟಾದ ಸಂಭವನೀಯ ಸೆಟ್ ಅನ್ನು ವಿವರಿಸಲು ಕೆಲವು ಭಾಷೆ. ಇಲ್ಲಿಯೇ ಸಾಮ್ಯತೆಗಳು ಕೊನೆಗೊಳ್ಳುತ್ತವೆ. ಪುಟದಿಂದ ಇದ್ದರೆ MTP ಪ್ರೋಟೋಕಾಲ್, ಅಥವಾ ಅಧಿಕೃತ ಕ್ಲೈಂಟ್‌ನ ಮೂಲ ಮರದಿಂದ, ನಾವು ಕೆಲವು ಸ್ಕೀಮಾವನ್ನು ತೆರೆಯಲು ಪ್ರಯತ್ನಿಸುತ್ತೇವೆ, ನಾವು ಈ ರೀತಿಯದನ್ನು ನೋಡುತ್ತೇವೆ:

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 ನ ಸೀಮಿತ ಉಪವಿಭಾಗವನ್ನು ಮಾತ್ರ ಬಳಸಲಾಗಿದೆ

ಹೇಳಿದಂತೆ ಲಿಯೋನೆರ್ಡ್ ಚಾನಲ್‌ನಲ್ಲಿ #perl FreeNode IRC ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿ, ಅವರು ಟೆಲಿಗ್ರಾಮ್‌ನಿಂದ ಮ್ಯಾಟ್ರಿಕ್ಸ್‌ಗೆ ಗೇಟ್ ಅನ್ನು ಅಳವಡಿಸಲು ಪ್ರಯತ್ನಿಸಿದರು (ಉಲ್ಲೇಖದ ಅನುವಾದವು ಮೆಮೊರಿಯಿಂದ ತಪ್ಪಾಗಿದೆ):

ಯಾರೋ ಮೊದಲ ಬಾರಿಗೆ ಥಿಯರಿಯನ್ನು ಟೈಪ್ ಮಾಡಲು ಪರಿಚಯಿಸಿದರು, ಉತ್ಸುಕರಾದರು ಮತ್ತು ಅದರೊಂದಿಗೆ ಆಟವಾಡಲು ಪ್ರಾರಂಭಿಸಿದರು, ಆಚರಣೆಯಲ್ಲಿ ಇದು ಅಗತ್ಯವಿದೆಯೇ ಎಂದು ನಿಜವಾಗಿಯೂ ಕಾಳಜಿ ವಹಿಸಲಿಲ್ಲ.

ನೀವೇ ನೋಡಿ, ಬೇರ್-ಟೈಪ್ಸ್ (ಇಂಟ್, ಲಾಂಗ್, ಇತ್ಯಾದಿ) ಪ್ರಾಥಮಿಕವಾಗಿ ಏನಾದರೂ ಪ್ರಶ್ನೆಗಳನ್ನು ಹುಟ್ಟುಹಾಕದಿದ್ದರೆ - ಅಂತಿಮವಾಗಿ ಅವುಗಳನ್ನು ಕೈಯಾರೆ ಕಾರ್ಯಗತಗೊಳಿಸಬೇಕು - ಉದಾಹರಣೆಗೆ, ಅವುಗಳಿಂದ ಪಡೆಯುವ ಪ್ರಯತ್ನವನ್ನು ತೆಗೆದುಕೊಳ್ಳೋಣ. ವೆಕ್ಟರ್. ಅಂದರೆ, ವಾಸ್ತವವಾಗಿ, ರಚನೆ, ನೀವು ಫಲಿತಾಂಶದ ವಸ್ತುಗಳನ್ನು ಅವುಗಳ ಸರಿಯಾದ ಹೆಸರುಗಳಿಂದ ಕರೆದರೆ.

ಆದರೆ ಮೊದಲು

ಅಧಿಕೃತ ದಸ್ತಾವೇಜನ್ನು ಓದದವರಿಗೆ TL ಸಿಂಟ್ಯಾಕ್ಸ್‌ನ ಉಪವಿಭಾಗದ ಕಿರು ವಿವರಣೆ

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

fixed#abcdef34 id:int = Type2;

fixedVec set:Vector<Type2> = FixedVec;

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

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

ವ್ಯಾಖ್ಯಾನ ಯಾವಾಗಲೂ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ ಕನ್ಸ್ಟ್ರಕ್ಟರ್, ಅದರ ನಂತರ ಐಚ್ಛಿಕವಾಗಿ (ಆಚರಣೆಯಲ್ಲಿ - ಯಾವಾಗಲೂ) ಚಿಹ್ನೆಯ ಮೂಲಕ # ಇರಬೇಕು CRC32 ಈ ಪ್ರಕಾರದ ಸಾಮಾನ್ಯ ವಿವರಣೆ ಸ್ಟ್ರಿಂಗ್‌ನಿಂದ. ಮುಂದೆ ಕ್ಷೇತ್ರಗಳ ವಿವರಣೆ ಬರುತ್ತದೆ; ಅವು ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದರೆ, ಪ್ರಕಾರವು ಖಾಲಿಯಾಗಿರಬಹುದು. ಇದೆಲ್ಲವೂ ಸಮಾನ ಚಿಹ್ನೆಯೊಂದಿಗೆ ಕೊನೆಗೊಳ್ಳುತ್ತದೆ, ಈ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಯಾವ ಪ್ರಕಾರದ ಹೆಸರು - ಅಂದರೆ, ವಾಸ್ತವವಾಗಿ, ಉಪಪ್ರಕಾರ - ಸೇರಿದೆ. ಸಮಾನ ಚಿಹ್ನೆಯ ಬಲಭಾಗದಲ್ಲಿರುವ ವ್ಯಕ್ತಿ ಬಹುರೂಪಿ - ಅಂದರೆ, ಹಲವಾರು ನಿರ್ದಿಷ್ಟ ಪ್ರಕಾರಗಳು ಅದಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗಬಹುದು.

ವ್ಯಾಖ್ಯಾನವು ಸಾಲಿನ ನಂತರ ಸಂಭವಿಸಿದರೆ ---functions---, ನಂತರ ಸಿಂಟ್ಯಾಕ್ಸ್ ಒಂದೇ ಆಗಿರುತ್ತದೆ, ಆದರೆ ಅರ್ಥವು ವಿಭಿನ್ನವಾಗಿರುತ್ತದೆ: ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಆರ್‌ಪಿಸಿ ಫಂಕ್ಷನ್‌ನ ಹೆಸರಾಗುತ್ತದೆ, ಕ್ಷೇತ್ರಗಳು ಪ್ಯಾರಾಮೀಟರ್‌ಗಳಾಗುತ್ತವೆ (ಅಂದರೆ, ಇದು ಕೆಳಗೆ ವಿವರಿಸಿದಂತೆ ಅದೇ ನಿರ್ದಿಷ್ಟ ರಚನೆಯಾಗಿ ಉಳಿಯುತ್ತದೆ , ಇದು ಸರಳವಾಗಿ ನಿಯೋಜಿತ ಅರ್ಥವಾಗಿರುತ್ತದೆ), ಮತ್ತು "ಬಹುರೂಪಿ ಪ್ರಕಾರ" - ಹಿಂತಿರುಗಿದ ಫಲಿತಾಂಶದ ಪ್ರಕಾರ. ನಿಜ, ಇದು ಇನ್ನೂ ಬಹುರೂಪಿಯಾಗಿ ಉಳಿಯುತ್ತದೆ - ವಿಭಾಗದಲ್ಲಿ ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ ---types---, ಆದರೆ ಈ ಕನ್ಸ್ಟ್ರಕ್ಟರ್ ಅನ್ನು "ಪರಿಗಣಿಸಲಾಗುವುದಿಲ್ಲ". ಕರೆಯಲಾದ ಕಾರ್ಯಗಳ ಪ್ರಕಾರಗಳನ್ನು ಅವುಗಳ ವಾದಗಳಿಂದ ಓವರ್‌ಲೋಡ್ ಮಾಡುವುದು, ಅಂದರೆ. ಕೆಲವು ಕಾರಣಗಳಿಗಾಗಿ, C++ ನಲ್ಲಿರುವಂತೆ ಒಂದೇ ಹೆಸರಿನ ಆದರೆ ವಿಭಿನ್ನ ಸಹಿಗಳೊಂದಿಗೆ ಹಲವಾರು ಕಾರ್ಯಗಳನ್ನು TL ನಲ್ಲಿ ಒದಗಿಸಲಾಗಿಲ್ಲ.

OOP ಇಲ್ಲದಿದ್ದರೆ "ಕನ್ಸ್ಟ್ರಕ್ಟರ್" ಮತ್ತು "ಪಾಲಿಮಾರ್ಫಿಕ್" ಏಕೆ? ಒಳ್ಳೆಯದು, ವಾಸ್ತವವಾಗಿ, ಯಾರಾದರೂ ಇದನ್ನು OOP ಪರಿಭಾಷೆಯಲ್ಲಿ ಯೋಚಿಸುವುದು ಸುಲಭವಾಗುತ್ತದೆ - ಅಮೂರ್ತ ವರ್ಗವಾಗಿ ಪಾಲಿಮಾರ್ಫಿಕ್ ಪ್ರಕಾರ, ಮತ್ತು ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ಗಳು ಅದರ ನೇರ ವಂಶಸ್ಥರು, ಮತ್ತು final ಹಲವಾರು ಭಾಷೆಗಳ ಪರಿಭಾಷೆಯಲ್ಲಿ. ವಾಸ್ತವವಾಗಿ, ಸಹಜವಾಗಿ, ಇಲ್ಲಿ ಮಾತ್ರ ಹೋಲಿಕೆ OO ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಭಾಷೆಗಳಲ್ಲಿ ನೈಜ ಓವರ್‌ಲೋಡ್ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ವಿಧಾನಗಳೊಂದಿಗೆ. ಇಲ್ಲಿ ಕೇವಲ ಡೇಟಾ ರಚನೆಗಳು ಇರುವುದರಿಂದ, ಯಾವುದೇ ವಿಧಾನಗಳಿಲ್ಲ (ಆದರೂ ಕಾರ್ಯಗಳು ಮತ್ತು ವಿಧಾನಗಳ ವಿವರಣೆಯು ಅವರು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ ಎಂದು ತಲೆಯಲ್ಲಿ ಗೊಂದಲವನ್ನು ಸೃಷ್ಟಿಸಲು ಸಾಕಷ್ಟು ಸಮರ್ಥವಾಗಿದೆ, ಆದರೆ ಇದು ಬೇರೆ ವಿಷಯವಾಗಿದೆ) - ನೀವು ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಅನ್ನು ಮೌಲ್ಯವಾಗಿ ಯೋಚಿಸಬಹುದು ಯಾವುದು ನಿರ್ಮಿಸಲಾಗುತ್ತಿದೆ ಬೈಟ್ ಸ್ಟ್ರೀಮ್ ಓದುವಾಗ ಟೈಪ್ ಮಾಡಿ.

ಇದು ಹೇಗೆ ಸಂಭವಿಸುತ್ತದೆ? ಯಾವಾಗಲೂ 4 ಬೈಟ್‌ಗಳನ್ನು ಓದುವ ಡಿಸೈಲೈಸರ್ ಮೌಲ್ಯವನ್ನು ನೋಡುತ್ತದೆ 0xcrc32 - ಮತ್ತು ಮುಂದೆ ಏನಾಗುತ್ತದೆ ಎಂಬುದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುತ್ತದೆ field1 ಪ್ರಕಾರದೊಂದಿಗೆ int, ಅಂದರೆ ನಿಖರವಾಗಿ 4 ಬೈಟ್‌ಗಳನ್ನು ಓದುತ್ತದೆ, ಇದರ ಮೇಲೆ ಟೈಪ್‌ನೊಂದಿಗೆ ಮಿತಿಮೀರಿದ ಕ್ಷೇತ್ರ PolymorType ಓದಿದೆ. ನೋಡುತ್ತಾನೆ 0x2crc32 ಮತ್ತು ಮುಂದೆ ಎರಡು ಕ್ಷೇತ್ರಗಳಿವೆ ಎಂದು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುತ್ತದೆ, ಮೊದಲು long, ಅಂದರೆ ನಾವು 8 ಬೈಟ್‌ಗಳನ್ನು ಓದುತ್ತೇವೆ. ತದನಂತರ ಮತ್ತೆ ಒಂದು ಸಂಕೀರ್ಣ ಪ್ರಕಾರ, ಇದು ಅದೇ ರೀತಿಯಲ್ಲಿ deserialized ಆಗಿದೆ. ಉದಾಹರಣೆಗೆ, Type3 ಕ್ರಮವಾಗಿ ಎರಡು ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ಗಳನ್ನು ಸರ್ಕ್ಯೂಟ್‌ನಲ್ಲಿ ಘೋಷಿಸಬಹುದು, ನಂತರ ಅವರು ಭೇಟಿಯಾಗಬೇಕು 0x12abcd34, ಅದರ ನಂತರ ನೀವು ಇನ್ನೂ 4 ಬೈಟ್‌ಗಳನ್ನು ಓದಬೇಕು int, ಅಥವಾ 0x6789cdef, ಅದರ ನಂತರ ಏನೂ ಇರುವುದಿಲ್ಲ. ಬೇರೆ ಯಾವುದಾದರೂ - ನೀವು ವಿನಾಯಿತಿಯನ್ನು ಎಸೆಯುವ ಅಗತ್ಯವಿದೆ. ಹೇಗಾದರೂ, ಇದರ ನಂತರ ನಾವು 4 ಬೈಟ್ಗಳನ್ನು ಓದುವುದಕ್ಕೆ ಹಿಂತಿರುಗುತ್ತೇವೆ int ರೈಟ್ರಸ್ »СЏ field_c в constructorTwo ಮತ್ತು ಅದರೊಂದಿಗೆ ನಾವು ನಮ್ಮ ಓದುವಿಕೆಯನ್ನು ಮುಗಿಸುತ್ತೇವೆ PolymorType.

ಅಂತಿಮವಾಗಿ, ನೀವು ಸಿಕ್ಕಿಬಿದ್ದರೆ 0xdeadcrc ಗೆ constructorThree, ನಂತರ ಎಲ್ಲವೂ ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾಗುತ್ತದೆ. ನಮ್ಮ ಮೊದಲ ಕ್ಷೇತ್ರ bit_flags_of_what_really_present ಪ್ರಕಾರದೊಂದಿಗೆ # - ವಾಸ್ತವವಾಗಿ, ಇದು ಪ್ರಕಾರಕ್ಕೆ ಕೇವಲ ಅಲಿಯಾಸ್ ಆಗಿದೆ nat, "ನೈಸರ್ಗಿಕ ಸಂಖ್ಯೆ" ಎಂದರ್ಥ. ಅಂದರೆ, ವಾಸ್ತವವಾಗಿ, ಸಹಿ ಮಾಡದ ಇಂಟ್ ಎಂದರೆ, ನೈಜ ಸರ್ಕ್ಯೂಟ್‌ಗಳಲ್ಲಿ ಸಹಿ ಮಾಡದ ಸಂಖ್ಯೆಗಳು ಸಂಭವಿಸಿದಾಗ ಮಾತ್ರ. ಆದ್ದರಿಂದ, ಮುಂದಿನದು ಪ್ರಶ್ನಾರ್ಥಕ ಚಿಹ್ನೆಯೊಂದಿಗೆ ನಿರ್ಮಾಣವಾಗಿದೆ, ಅಂದರೆ ಈ ಕ್ಷೇತ್ರವು - ಸೂಚಿಸಲಾದ ಕ್ಷೇತ್ರದಲ್ಲಿ ಅನುಗುಣವಾದ ಬಿಟ್ ಅನ್ನು ಹೊಂದಿಸಿದರೆ ಮಾತ್ರ ಅದು ತಂತಿಯ ಮೇಲೆ ಇರುತ್ತದೆ (ಸರಿಸುಮಾರು ತ್ರಯಾತ್ಮಕ ಆಪರೇಟರ್‌ನಂತೆ). ಆದ್ದರಿಂದ, ಈ ಬಿಟ್ ಅನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ ಎಂದು ಭಾವಿಸೋಣ, ಅಂದರೆ ಮುಂದೆ ನಾವು ಅಂತಹ ಕ್ಷೇತ್ರವನ್ನು ಓದಬೇಕಾಗಿದೆ Type, ಇದು ನಮ್ಮ ಉದಾಹರಣೆಯಲ್ಲಿ 2 ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ಗಳನ್ನು ಹೊಂದಿದೆ. ಒಂದು ಖಾಲಿಯಾಗಿದೆ (ಗುರುತಿಸುವಿಕೆಯನ್ನು ಮಾತ್ರ ಒಳಗೊಂಡಿರುತ್ತದೆ), ಇನ್ನೊಂದು ಕ್ಷೇತ್ರವನ್ನು ಹೊಂದಿದೆ ids ಪ್ರಕಾರದೊಂದಿಗೆ ids:Vector<long>.

ಟೆಂಪ್ಲೇಟ್‌ಗಳು ಮತ್ತು ಜೆನೆರಿಕ್ಸ್ ಎರಡೂ ಸಾಧಕ ಅಥವಾ ಜಾವಾದಲ್ಲಿವೆ ಎಂದು ನೀವು ಭಾವಿಸಬಹುದು. ಆದರೆ ಇಲ್ಲ. ಬಹುತೇಕ. ಈ ಏಕೈಕ ನೈಜ ಸರ್ಕ್ಯೂಟ್‌ಗಳಲ್ಲಿ ಕೋನ ಆವರಣಗಳನ್ನು ಬಳಸುವ ಸಂದರ್ಭದಲ್ಲಿ, ಮತ್ತು ಇದನ್ನು ವೆಕ್ಟರ್‌ಗೆ ಮಾತ್ರ ಬಳಸಲಾಗುತ್ತದೆ. ಬೈಟ್ ಸ್ಟ್ರೀಮ್‌ನಲ್ಲಿ, ಇವುಗಳು ವೆಕ್ಟರ್ ಪ್ರಕಾರಕ್ಕೆ 4 CRC32 ಬೈಟ್‌ಗಳಾಗಿರುತ್ತವೆ, ಯಾವಾಗಲೂ ಒಂದೇ ಆಗಿರುತ್ತವೆ, ನಂತರ 4 ಬೈಟ್‌ಗಳು - ರಚನೆಯ ಅಂಶಗಳ ಸಂಖ್ಯೆ, ಮತ್ತು ನಂತರ ಈ ಅಂಶಗಳು.

ಧಾರಾವಾಹಿ ಯಾವಾಗಲೂ 4 ಬೈಟ್‌ಗಳ ಪದಗಳಲ್ಲಿ ಸಂಭವಿಸುತ್ತದೆ ಎಂಬ ಅಂಶವನ್ನು ಇದಕ್ಕೆ ಸೇರಿಸಿ, ಎಲ್ಲಾ ಪ್ರಕಾರಗಳು ಅದರ ಗುಣಕಗಳಾಗಿವೆ - ಅಂತರ್ನಿರ್ಮಿತ ಪ್ರಕಾರಗಳನ್ನು ಸಹ ವಿವರಿಸಲಾಗಿದೆ bytes и string ಉದ್ದದ ಹಸ್ತಚಾಲಿತ ಧಾರಾವಾಹಿ ಮತ್ತು 4 ರಿಂದ ಈ ಜೋಡಣೆಯೊಂದಿಗೆ - ಅಲ್ಲದೆ, ಇದು ಸಾಮಾನ್ಯ ಮತ್ತು ತುಲನಾತ್ಮಕವಾಗಿ ಪರಿಣಾಮಕಾರಿ ಎಂದು ತೋರುತ್ತದೆ? TL ಅನ್ನು ಪರಿಣಾಮಕಾರಿ ಬೈನರಿ ಧಾರಾವಾಹಿ ಎಂದು ಹೇಳಲಾಗಿದ್ದರೂ, ಬೂಲಿಯನ್ ಮೌಲ್ಯಗಳು ಮತ್ತು ಏಕ-ಅಕ್ಷರ ಸ್ಟ್ರಿಂಗ್‌ಗಳನ್ನು 4 ಬೈಟ್‌ಗಳಿಗೆ ವಿಸ್ತರಿಸುವುದರೊಂದಿಗೆ, ಅವರೊಂದಿಗೆ ನರಕಕ್ಕೆ, JSON ಇನ್ನೂ ಹೆಚ್ಚು ದಪ್ಪವಾಗಿರುತ್ತದೆಯೇ? ನೋಡಿ, ಬಿಟ್ ಫ್ಲ್ಯಾಗ್‌ಗಳ ಮೂಲಕ ಅನಗತ್ಯ ಕ್ಷೇತ್ರಗಳನ್ನು ಸಹ ಬಿಟ್ಟುಬಿಡಬಹುದು, ಎಲ್ಲವೂ ಸಾಕಷ್ಟು ಉತ್ತಮವಾಗಿದೆ ಮತ್ತು ಭವಿಷ್ಯಕ್ಕಾಗಿ ವಿಸ್ತರಿಸಬಹುದು, ಆದ್ದರಿಂದ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ಗೆ ಹೊಸ ಐಚ್ಛಿಕ ಕ್ಷೇತ್ರಗಳನ್ನು ಏಕೆ ಸೇರಿಸಬಾರದು?..

ಆದರೆ ಇಲ್ಲ, ನೀವು ನನ್ನ ಸಂಕ್ಷಿಪ್ತ ವಿವರಣೆಯನ್ನು ಓದದಿದ್ದರೆ, ಆದರೆ ಸಂಪೂರ್ಣ ದಸ್ತಾವೇಜನ್ನು, ಮತ್ತು ಅನುಷ್ಠಾನದ ಬಗ್ಗೆ ಯೋಚಿಸಿ. ಮೊದಲನೆಯದಾಗಿ, ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ನ CRC32 ಅನ್ನು ಸ್ಕೀಮ್‌ನ ಪಠ್ಯ ವಿವರಣೆಯ ಸಾಮಾನ್ಯಗೊಳಿಸಿದ ರೇಖೆಯ ಪ್ರಕಾರ ಲೆಕ್ಕಹಾಕಲಾಗುತ್ತದೆ (ಹೆಚ್ಚುವರಿ ಜಾಗವನ್ನು ತೆಗೆದುಹಾಕಿ, ಇತ್ಯಾದಿ.) - ಆದ್ದರಿಂದ ಹೊಸ ಕ್ಷೇತ್ರವನ್ನು ಸೇರಿಸಿದರೆ, ಪ್ರಕಾರದ ವಿವರಣೆ ಸಾಲು ಬದಲಾಗುತ್ತದೆ ಮತ್ತು ಆದ್ದರಿಂದ ಅದರ CRC32 ಮತ್ತು , ಪರಿಣಾಮವಾಗಿ, ಧಾರಾವಾಹಿ. ಮತ್ತು ಹಳೆಯ ಕ್ಲೈಂಟ್ ಹೊಸ ಫ್ಲ್ಯಾಗ್‌ಗಳನ್ನು ಹೊಂದಿರುವ ಕ್ಷೇತ್ರವನ್ನು ಸ್ವೀಕರಿಸಿದರೆ ಮತ್ತು ಮುಂದೆ ಅವರೊಂದಿಗೆ ಏನು ಮಾಡಬೇಕೆಂದು ಅವನಿಗೆ ತಿಳಿದಿಲ್ಲದಿದ್ದರೆ ಏನು ಮಾಡುತ್ತಾನೆ?

ಎರಡನೆಯದಾಗಿ, ನೆನಪಿಟ್ಟುಕೊಳ್ಳೋಣ CRC32, ಇಲ್ಲಿ ಮೂಲಭೂತವಾಗಿ ಬಳಸಲಾಗಿದೆ ಹ್ಯಾಶ್ ಕಾರ್ಯಗಳು ಯಾವ ಪ್ರಕಾರವನ್ನು (ಡಿ) ಧಾರಾವಾಹಿ ಮಾಡಲಾಗುತ್ತಿದೆ ಎಂಬುದನ್ನು ಅನನ್ಯವಾಗಿ ನಿರ್ಧರಿಸಲು. ಇಲ್ಲಿ ನಾವು ಘರ್ಷಣೆಯ ಸಮಸ್ಯೆಯನ್ನು ಎದುರಿಸುತ್ತಿದ್ದೇವೆ - ಮತ್ತು ಇಲ್ಲ, ಸಂಭವನೀಯತೆ 232 ರಲ್ಲಿ ಒಂದಲ್ಲ, ಆದರೆ ಹೆಚ್ಚು. ಸಂವಹನ ಚಾನಲ್‌ನಲ್ಲಿ ದೋಷಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಲು (ಮತ್ತು ಸರಿಯಾದ) CRC32 ಅನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿದೆ ಮತ್ತು ಅದರ ಪ್ರಕಾರ ಈ ಗುಣಲಕ್ಷಣಗಳನ್ನು ಇತರರಿಗೆ ಹಾನಿಯಾಗುವಂತೆ ಸುಧಾರಿಸುತ್ತದೆ ಎಂದು ಯಾರು ನೆನಪಿಸಿಕೊಂಡರು? ಉದಾಹರಣೆಗೆ, ಬೈಟ್‌ಗಳನ್ನು ಮರುಹೊಂದಿಸುವ ಬಗ್ಗೆ ಇದು ಹೆದರುವುದಿಲ್ಲ: ನೀವು CRC32 ಅನ್ನು ಎರಡು ಸಾಲುಗಳಿಂದ ಲೆಕ್ಕ ಹಾಕಿದರೆ, ಎರಡನೆಯದರಲ್ಲಿ ನೀವು ಮೊದಲ 4 ಬೈಟ್‌ಗಳನ್ನು ಮುಂದಿನ 4 ಬೈಟ್‌ಗಳೊಂದಿಗೆ ವಿನಿಮಯ ಮಾಡಿಕೊಳ್ಳಿ - ಅದು ಒಂದೇ ಆಗಿರುತ್ತದೆ. ನಮ್ಮ ಇನ್‌ಪುಟ್ ಲ್ಯಾಟಿನ್ ವರ್ಣಮಾಲೆಯಿಂದ (ಮತ್ತು ಸ್ವಲ್ಪ ವಿರಾಮಚಿಹ್ನೆ) ಪಠ್ಯ ತಂತಿಗಳಾಗಿದ್ದರೆ ಮತ್ತು ಈ ಹೆಸರುಗಳು ನಿರ್ದಿಷ್ಟವಾಗಿ ಯಾದೃಚ್ಛಿಕವಾಗಿಲ್ಲದಿದ್ದರೆ, ಅಂತಹ ಮರುಜೋಡಣೆಯ ಸಾಧ್ಯತೆಯು ಹೆಚ್ಚು ಹೆಚ್ಚಾಗುತ್ತದೆ.

ಅಂದಹಾಗೆ, ಅಲ್ಲಿ ಏನಿದೆ ಎಂದು ಯಾರು ಪರಿಶೀಲಿಸಿದರು? ನಿಜವಾಗಿಯೂ CRC32? ಆರಂಭಿಕ ಮೂಲ ಕೋಡ್‌ಗಳಲ್ಲಿ ಒಂದಾದ (ವಾಲ್ಟ್‌ಮ್ಯಾನ್‌ಗಿಂತ ಮುಂಚೆಯೇ) ಹ್ಯಾಶ್ ಕಾರ್ಯವನ್ನು ಹೊಂದಿದ್ದು ಅದು ಪ್ರತಿ ಅಕ್ಷರವನ್ನು 239 ಸಂಖ್ಯೆಯಿಂದ ಗುಣಿಸುತ್ತದೆ, ಈ ಜನರಿಗೆ ತುಂಬಾ ಪ್ರಿಯವಾಗಿದೆ, ಹ ಹ!

ಅಂತಿಮವಾಗಿ, ಸರಿ, ಕ್ಷೇತ್ರ ಪ್ರಕಾರವನ್ನು ಹೊಂದಿರುವ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ಗಳು ಎಂದು ನಾವು ಅರಿತುಕೊಂಡೆವು Vector<int> и Vector<PolymorType> ವಿಭಿನ್ನ CRC32 ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆನ್‌ಲೈನ್ ಕಾರ್ಯಕ್ಷಮತೆಯ ಬಗ್ಗೆ ಏನು? ಮತ್ತು ಸೈದ್ಧಾಂತಿಕ ದೃಷ್ಟಿಕೋನದಿಂದ, ಇದು ಪ್ರಕಾರದ ಭಾಗವಾಗುತ್ತದೆಯೇ? ನಾವು ಹತ್ತು ಸಾವಿರ ಸಂಖ್ಯೆಗಳ ಶ್ರೇಣಿಯನ್ನು ಹಾದು ಹೋಗುತ್ತೇವೆ ಎಂದು ಹೇಳೋಣ Vector<int> ಎಲ್ಲವೂ ಸ್ಪಷ್ಟವಾಗಿದೆ, ಉದ್ದ ಮತ್ತು ಇನ್ನೊಂದು 40000 ಬೈಟ್‌ಗಳು. ಈ ವೇಳೆ ಏನು Vector<Type2>, ಇದು ಕೇವಲ ಒಂದು ಕ್ಷೇತ್ರವನ್ನು ಒಳಗೊಂಡಿದೆ int ಮತ್ತು ಇದು ಪ್ರಕಾರದಲ್ಲಿ ಏಕಾಂಗಿಯಾಗಿದೆ - ನಾವು 10000xabcdef0 ಅನ್ನು 34 ಬಾರಿ ಪುನರಾವರ್ತಿಸಬೇಕು ಮತ್ತು ನಂತರ 4 ಬೈಟ್‌ಗಳು int, ಅಥವಾ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ನಿಂದ ನಮಗೆ ಅದನ್ನು ಸ್ವತಂತ್ರಗೊಳಿಸಲು ಭಾಷೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ fixedVec ಮತ್ತು 80000 ಬೈಟ್‌ಗಳ ಬದಲಿಗೆ, ಮತ್ತೆ 40000 ಮಾತ್ರ ವರ್ಗಾಯಿಸುವುದೇ?

ಇದು ನಿಷ್ಫಲ ಸೈದ್ಧಾಂತಿಕ ಪ್ರಶ್ನೆಯಲ್ಲ - ನೀವು ಗುಂಪಿನ ಬಳಕೆದಾರರ ಪಟ್ಟಿಯನ್ನು ಸ್ವೀಕರಿಸುತ್ತೀರಿ ಎಂದು ಊಹಿಸಿಕೊಳ್ಳಿ, ಅವರಲ್ಲಿ ಪ್ರತಿಯೊಬ್ಬರೂ ಐಡಿ, ಮೊದಲ ಹೆಸರು, ಕೊನೆಯ ಹೆಸರನ್ನು ಹೊಂದಿದ್ದಾರೆ - ಮೊಬೈಲ್ ಸಂಪರ್ಕದ ಮೂಲಕ ವರ್ಗಾಯಿಸಲಾದ ಡೇಟಾದ ಪ್ರಮಾಣದಲ್ಲಿ ವ್ಯತ್ಯಾಸವು ಗಮನಾರ್ಹವಾಗಿರುತ್ತದೆ. ಇದು ನಿಖರವಾಗಿ ಟೆಲಿಗ್ರಾಮ್ ಧಾರಾವಾಹಿಯ ಪರಿಣಾಮಕಾರಿತ್ವವನ್ನು ನಮಗೆ ಜಾಹೀರಾತು ಮಾಡಲಾಗಿದೆ.

ಆದ್ದರಿಂದ…

ವೆಕ್ಟರ್, ಇದು ಎಂದಿಗೂ ಬಿಡುಗಡೆಯಾಗಲಿಲ್ಲ

ನೀವು ಸಂಯೋಜಕಗಳ ವಿವರಣೆಯ ಪುಟಗಳ ಮೂಲಕ ವೇಡ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದರೆ, ವೆಕ್ಟರ್ (ಮತ್ತು ಮ್ಯಾಟ್ರಿಕ್ಸ್ ಕೂಡ) ಔಪಚಾರಿಕವಾಗಿ ಹಲವಾರು ಹಾಳೆಗಳ ಟುಪಲ್‌ಗಳ ಮೂಲಕ ಔಟ್‌ಪುಟ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವುದನ್ನು ನೀವು ನೋಡುತ್ತೀರಿ. ಆದರೆ ಕೊನೆಯಲ್ಲಿ ಅವರು ಮರೆತುಬಿಡುತ್ತಾರೆ, ಅಂತಿಮ ಹಂತವನ್ನು ಬಿಟ್ಟುಬಿಡಲಾಗುತ್ತದೆ ಮತ್ತು ವೆಕ್ಟರ್ನ ವ್ಯಾಖ್ಯಾನವನ್ನು ಸರಳವಾಗಿ ನೀಡಲಾಗುತ್ತದೆ, ಅದು ಇನ್ನೂ ಒಂದು ಪ್ರಕಾರಕ್ಕೆ ಸಂಬಂಧಿಸಿಲ್ಲ. ಏನು ವಿಷಯ? ಭಾಷೆಗಳಲ್ಲಿ ಪ್ರೋಗ್ರಾಮಿಂಗ್, ವಿಶೇಷವಾಗಿ ಕ್ರಿಯಾತ್ಮಕವಾದವುಗಳು, ರಚನೆಯನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ ವಿವರಿಸಲು ಇದು ಸಾಕಷ್ಟು ವಿಶಿಷ್ಟವಾಗಿದೆ - ಅದರ ಸೋಮಾರಿಯಾದ ಮೌಲ್ಯಮಾಪನದೊಂದಿಗೆ ಕಂಪೈಲರ್ ಎಲ್ಲವನ್ನೂ ಸ್ವತಃ ಅರ್ಥಮಾಡಿಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ಮಾಡುತ್ತದೆ. ಭಾಷೆಯಲ್ಲಿ ಡೇಟಾ ಧಾರಾವಾಹಿ ಬೇಕಾಗಿರುವುದು ದಕ್ಷತೆ: ಸರಳವಾಗಿ ವಿವರಿಸಲು ಸಾಕು ಪಟ್ಟಿ, ಅಂದರೆ ಎರಡು ಅಂಶಗಳ ರಚನೆ - ಮೊದಲನೆಯದು ಡೇಟಾ ಎಲಿಮೆಂಟ್, ಎರಡನೆಯದು ಅದೇ ರಚನೆ ಅಥವಾ ಬಾಲಕ್ಕೆ ಖಾಲಿ ಜಾಗ (ಪ್ಯಾಕ್ (cons) ಲಿಸ್ಪ್ನಲ್ಲಿ). ಆದರೆ ಇದು ನಿಸ್ಸಂಶಯವಾಗಿ ಅಗತ್ಯವಿರುತ್ತದೆ ಪ್ರತಿಯೊಂದರಲ್ಲೂ ಅಂಶವು ಅದರ ಪ್ರಕಾರವನ್ನು ವಿವರಿಸಲು ಹೆಚ್ಚುವರಿ 4 ಬೈಟ್‌ಗಳನ್ನು (TL ನಲ್ಲಿನ ಸಂದರ್ಭದಲ್ಲಿ CRC32) ಕಳೆಯುತ್ತದೆ. ಒಂದು ಶ್ರೇಣಿಯನ್ನು ಸಹ ಸುಲಭವಾಗಿ ವಿವರಿಸಬಹುದು ಸ್ಥಿರ ಗಾತ್ರ, ಆದರೆ ಮುಂಚಿತವಾಗಿ ಅಜ್ಞಾತ ಉದ್ದದ ರಚನೆಯ ಸಂದರ್ಭದಲ್ಲಿ, ನಾವು ಒಡೆಯುತ್ತೇವೆ.

ಆದ್ದರಿಂದ, TL ವೆಕ್ಟರ್ ಅನ್ನು ಔಟ್ಪುಟ್ ಮಾಡಲು ಅನುಮತಿಸುವುದಿಲ್ಲವಾದ್ದರಿಂದ, ಅದನ್ನು ಬದಿಯಲ್ಲಿ ಸೇರಿಸಬೇಕಾಗಿತ್ತು. ಅಂತಿಮವಾಗಿ ದಸ್ತಾವೇಜನ್ನು ಹೇಳುತ್ತದೆ:

ಸೀರಿಯಲೈಸೇಶನ್ ಯಾವಾಗಲೂ ಅದೇ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ “ವೆಕ್ಟರ್” ಅನ್ನು ಬಳಸುತ್ತದೆ (const 0x1cb5c415 = crc32(“ವೆಕ್ಟರ್ t:ಟೈಪ್ # [ t ] = ವೆಕ್ಟರ್ t”) ಇದು ಟೈಪ್ t ನ ವೇರಿಯಬಲ್‌ನ ನಿರ್ದಿಷ್ಟ ಮೌಲ್ಯವನ್ನು ಅವಲಂಬಿಸಿಲ್ಲ.

ಐಚ್ಛಿಕ ಪ್ಯಾರಾಮೀಟರ್ t ಯ ಮೌಲ್ಯವು ಧಾರಾವಾಹಿಯಲ್ಲಿ ಒಳಗೊಂಡಿರುವುದಿಲ್ಲ ಏಕೆಂದರೆ ಇದು ಫಲಿತಾಂಶದ ಪ್ರಕಾರದಿಂದ ಪಡೆಯಲ್ಪಟ್ಟಿದೆ (ಯಾವಾಗಲೂ ಡೀಸರಲೈಸೇಶನ್‌ಗೆ ಮುಂಚಿತವಾಗಿ ತಿಳಿದಿರುತ್ತದೆ).

ಹತ್ತಿರದಿಂದ ನೋಡಿ: vector {t:Type} # [ t ] = Vector t - ಆದರೆ ಎಲ್ಲಿಯೂ ಇಲ್ಲ ಈ ವ್ಯಾಖ್ಯಾನವು ಮೊದಲ ಸಂಖ್ಯೆಯು ವೆಕ್ಟರ್‌ನ ಉದ್ದಕ್ಕೆ ಸಮನಾಗಿರಬೇಕು ಎಂದು ಹೇಳುವುದಿಲ್ಲ! ಮತ್ತು ಅದು ಎಲ್ಲಿಂದಲಾದರೂ ಬರುವುದಿಲ್ಲ. ಇದನ್ನು ಮನಸ್ಸಿನಲ್ಲಿಟ್ಟುಕೊಳ್ಳಬೇಕು ಮತ್ತು ನಿಮ್ಮ ಕೈಗಳಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸಬೇಕು. ಬೇರೆಡೆ, ದಸ್ತಾವೇಜನ್ನು ಪ್ರಾಮಾಣಿಕವಾಗಿ ಈ ಪ್ರಕಾರವು ನಿಜವಲ್ಲ ಎಂದು ಉಲ್ಲೇಖಿಸುತ್ತದೆ:

ವೆಕ್ಟರ್ ಟಿ ಪಾಲಿಮಾರ್ಫಿಕ್ ಸ್ಯೂಡೋಟೈಪ್ ಒಂದು "ಟೈಪ್" ಆಗಿದ್ದು, ಅದರ ಮೌಲ್ಯವು ಬಾಕ್ಸ್ ಅಥವಾ ಬೇರ್ ಯಾವುದೇ ಪ್ರಕಾರದ ಮೌಲ್ಯಗಳ ಅನುಕ್ರಮವಾಗಿದೆ.

... ಆದರೆ ಅದರ ಮೇಲೆ ಕೇಂದ್ರೀಕರಿಸುವುದಿಲ್ಲ. ನೀವು, ಗಣಿತದ ವಿಸ್ತರಣೆಯ ಮೂಲಕ ಅಲೆದಾಡುವ ಮೂಲಕ ಬೇಸತ್ತಾಗ (ಬಹುಶಃ ನಿಮಗೆ ವಿಶ್ವವಿದ್ಯಾನಿಲಯದ ಕೋರ್ಸ್‌ನಿಂದಲೂ ತಿಳಿದಿರಬಹುದು), ತ್ಯಜಿಸಲು ನಿರ್ಧರಿಸಿ ಮತ್ತು ಪ್ರಾಯೋಗಿಕವಾಗಿ ಅದರೊಂದಿಗೆ ಹೇಗೆ ಕೆಲಸ ಮಾಡಬೇಕೆಂದು ನೋಡಿ, ಇದು ಗಂಭೀರವಾಗಿದೆ ಎಂಬ ಅನಿಸಿಕೆ ನಿಮ್ಮ ತಲೆಯಲ್ಲಿ ಉಳಿದಿದೆ. ಕೋರ್ ನಲ್ಲಿ ಗಣಿತ, ಇದು ಸ್ಪಷ್ಟವಾಗಿ ಕೂಲ್ ಪೀಪಲ್ (ಇಬ್ಬರು ಗಣಿತಜ್ಞರು - ACM ವಿಜೇತ) ಕಂಡುಹಿಡಿದರು, ಮತ್ತು ಕೇವಲ ಯಾರಾದರೂ ಅಲ್ಲ. ಗುರಿ - ಪ್ರದರ್ಶಿಸಲು - ಸಾಧಿಸಲಾಗಿದೆ.

ಮೂಲಕ, ಸಂಖ್ಯೆಯ ಬಗ್ಗೆ. ಅದನ್ನು ನಿಮಗೆ ನೆನಪಿಸೋಣ # ಇದು ಸಮಾನಾರ್ಥಕ ಪದವಾಗಿದೆ nat, ನೈಸರ್ಗಿಕ ಸಂಖ್ಯೆ:

ಪ್ರಕಾರದ ಅಭಿವ್ಯಕ್ತಿಗಳಿವೆ (ಟೈಪ್-ಎಕ್ಸ್‌ಪಿಆರ್) ಮತ್ತು ಸಂಖ್ಯಾ ಅಭಿವ್ಯಕ್ತಿಗಳು (nat-expr) ಆದಾಗ್ಯೂ, ಅವುಗಳನ್ನು ಅದೇ ರೀತಿಯಲ್ಲಿ ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ.

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

ಆದರೆ ವ್ಯಾಕರಣದಲ್ಲಿ ಅವುಗಳನ್ನು ಅದೇ ರೀತಿಯಲ್ಲಿ ವಿವರಿಸಲಾಗಿದೆ, ಅಂದರೆ. ಈ ವ್ಯತ್ಯಾಸವನ್ನು ಮತ್ತೊಮ್ಮೆ ನೆನಪಿನಲ್ಲಿಟ್ಟುಕೊಳ್ಳಬೇಕು ಮತ್ತು ಕೈಯಾರೆ ಅನುಷ್ಠಾನಕ್ಕೆ ತರಬೇಕು.

ಸರಿ, ಹೌದು, ಟೆಂಪ್ಲೇಟ್ ಪ್ರಕಾರಗಳು (vector<int>, vector<User>) ಸಾಮಾನ್ಯ ಗುರುತಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿರಿ (#1cb5c415), ಅಂದರೆ. ಕರೆ ಎಂದು ಘೋಷಿಸಲಾಗಿದೆ ಎಂದು ನಿಮಗೆ ತಿಳಿದಿದ್ದರೆ

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

ನಂತರ ನೀವು ಇನ್ನು ಮುಂದೆ ಕೇವಲ ವೆಕ್ಟರ್‌ಗಾಗಿ ಕಾಯುತ್ತಿಲ್ಲ, ಆದರೆ ಬಳಕೆದಾರರ ವೆಕ್ಟರ್. ನಿಖರವಾಗಿ, ಮಾಡಬೇಕಾದುದು ನಿರೀಕ್ಷಿಸಿ - ನೈಜ ಕೋಡ್‌ನಲ್ಲಿ, ಪ್ರತಿ ಅಂಶವು ಬೇರ್ ಪ್ರಕಾರವಲ್ಲದಿದ್ದರೆ, ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ ಮತ್ತು ಅನುಷ್ಠಾನದಲ್ಲಿ ಉತ್ತಮ ರೀತಿಯಲ್ಲಿ ಪರಿಶೀಲಿಸುವುದು ಅಗತ್ಯವಾಗಿರುತ್ತದೆ - ಆದರೆ ಈ ವೆಕ್ಟರ್‌ನ ಪ್ರತಿಯೊಂದು ಅಂಶದಲ್ಲಿ ನಮ್ಮನ್ನು ನಿಖರವಾಗಿ ಕಳುಹಿಸಲಾಗಿದೆ ಆ ಪ್ರಕಾರ? ಇದು ಕೆಲವು ರೀತಿಯ PHP ಆಗಿದ್ದರೆ, ಇದರಲ್ಲಿ ಒಂದು ಶ್ರೇಣಿಯು ವಿಭಿನ್ನ ಅಂಶಗಳಲ್ಲಿ ವಿಭಿನ್ನ ಪ್ರಕಾರಗಳನ್ನು ಹೊಂದಿರುತ್ತದೆ?

ಈ ಹಂತದಲ್ಲಿ ನೀವು ಯೋಚಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತೀರಿ - ಅಂತಹ TL ಅಗತ್ಯವಿದೆಯೇ? ಬಹುಶಃ ಕಾರ್ಟ್‌ಗೆ ಮಾನವ ಧಾರಾವಾಹಿಯನ್ನು ಬಳಸಲು ಸಾಧ್ಯವೇ, ಆಗ ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದ ಅದೇ ಪ್ರೋಟೋಬಫ್? ಅದು ಸಿದ್ಧಾಂತವಾಗಿತ್ತು, ಅಭ್ಯಾಸವನ್ನು ನೋಡೋಣ.

ಕೋಡ್‌ನಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ TL ಅನುಷ್ಠಾನಗಳು

ಡುರೊವ್ ಅವರ ಪಾಲನ್ನು ಮಾರಾಟ ಮಾಡುವ ಮೂಲಕ ಪ್ರಸಿದ್ಧ ಘಟನೆಗಳಿಗೆ ಮುಂಚೆಯೇ TL VKontakte ನ ಆಳದಲ್ಲಿ ಜನಿಸಿದರು ಮತ್ತು (ಖಂಡಿತವಾಗಿ), ಟೆಲಿಗ್ರಾಮ್‌ನ ಅಭಿವೃದ್ಧಿ ಪ್ರಾರಂಭವಾಗುವ ಮೊದಲೇ. ಮತ್ತು ತೆರೆದ ಮೂಲದಲ್ಲಿ ಮೊದಲ ಅನುಷ್ಠಾನದ ಮೂಲ ಕೋಡ್ ನೀವು ಬಹಳಷ್ಟು ತಮಾಷೆಯ ಊರುಗೋಲುಗಳನ್ನು ಕಾಣಬಹುದು. ಮತ್ತು ಟೆಲಿಗ್ರಾಮ್‌ನಲ್ಲಿ ಈಗ ಇರುವುದಕ್ಕಿಂತ ಹೆಚ್ಚು ಸಂಪೂರ್ಣವಾಗಿ ಭಾಷೆಯನ್ನು ಅಲ್ಲಿ ಅಳವಡಿಸಲಾಗಿದೆ. ಉದಾಹರಣೆಗೆ, ಸ್ಕೀಮ್‌ನಲ್ಲಿ ಹ್ಯಾಶ್‌ಗಳನ್ನು ಬಳಸಲಾಗುವುದಿಲ್ಲ (ಅಂದರೆ ಒಂದು ಅಂತರ್ನಿರ್ಮಿತ ಹುಸಿಮಾದರಿ (ವೆಕ್ಟರ್‌ನಂತೆ) ವಿಚಲನ ನಡವಳಿಕೆಯೊಂದಿಗೆ). ಅಥವಾ

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

ಇದು ಇಂಟ್ - ಟೈಪ್ ಜೋಡಿಗಳ ವೆಕ್ಟರ್ ಆಗಿ ಹ್ಯಾಶ್‌ಮ್ಯಾಪ್ ಟೆಂಪ್ಲೇಟ್ ಪ್ರಕಾರದ ವ್ಯಾಖ್ಯಾನವಾಗಿದೆ. C++ ನಲ್ಲಿ ಇದು ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:

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

ಆದ್ದರಿಂದ, alpha - ಕೀವರ್ಡ್! ಆದರೆ C ++ ನಲ್ಲಿ ಮಾತ್ರ ನೀವು T ಬರೆಯಬಹುದು, ಆದರೆ ನೀವು ಆಲ್ಫಾ, ಬೀಟಾ ಬರೆಯಬೇಕು ... ಆದರೆ 8 ಕ್ಕಿಂತ ಹೆಚ್ಚು ನಿಯತಾಂಕಗಳಿಲ್ಲ, ಅಲ್ಲಿ ಫ್ಯಾಂಟಸಿ ಕೊನೆಗೊಳ್ಳುತ್ತದೆ. ಒಮ್ಮೆ ಸೇಂಟ್ ಪೀಟರ್ಸ್ಬರ್ಗ್ನಲ್ಲಿ ಈ ರೀತಿಯ ಕೆಲವು ಸಂಭಾಷಣೆಗಳು ನಡೆದಿವೆ ಎಂದು ತೋರುತ್ತದೆ:

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

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

ಆದರೆ ಇದು "ಸಾಮಾನ್ಯವಾಗಿ" TL ನ ಮೊದಲ ಪ್ರಕಟಿತ ಅನುಷ್ಠಾನದ ಬಗ್ಗೆ. ಟೆಲಿಗ್ರಾಮ್ ಕ್ಲೈಂಟ್‌ಗಳಲ್ಲಿಯೇ ಅನುಷ್ಠಾನಗಳನ್ನು ಪರಿಗಣಿಸಲು ನಾವು ಮುಂದುವರಿಯೋಣ.

ವಾಸಿಲಿಗೆ ಮಾತು:

ವಾಸಿಲಿ, [09.10.18 17:07] ಎಲ್ಲಕ್ಕಿಂತ ಹೆಚ್ಚಾಗಿ, ಕತ್ತೆ ಬಿಸಿಯಾಗಿರುತ್ತದೆ ಏಕೆಂದರೆ ಅವರು ಅಮೂರ್ತತೆಯ ಗುಂಪನ್ನು ರಚಿಸಿದರು, ಮತ್ತು ನಂತರ ಅವುಗಳ ಮೇಲೆ ಬೋಲ್ಟ್ ಅನ್ನು ಬಡಿಯುತ್ತಾರೆ ಮತ್ತು ಕೋಡ್ ಜನರೇಟರ್ ಅನ್ನು ಊರುಗೋಲುಗಳಿಂದ ಮುಚ್ಚಿದರು.
ಪರಿಣಾಮವಾಗಿ, ಮೊದಲು ಡಾಕ್ pilot.jpg ನಿಂದ
ನಂತರ ಕೋಡ್ dzhekichan.webp ನಿಂದ

ಸಹಜವಾಗಿ, ಅಲ್ಗಾರಿದಮ್‌ಗಳು ಮತ್ತು ಗಣಿತಶಾಸ್ತ್ರದ ಪರಿಚಯವಿರುವ ಜನರಿಂದ, ಅವರು ಅಹೋ, ಉಲ್‌ಮನ್‌ಗಳನ್ನು ಓದಿದ್ದಾರೆ ಮತ್ತು ತಮ್ಮ DSL ಕಂಪೈಲರ್‌ಗಳನ್ನು ಬರೆಯಲು ದಶಕಗಳಿಂದ ಉದ್ಯಮದಲ್ಲಿ ವಾಸ್ತವಿಕ ಮಾನದಂಡವಾಗಿ ಮಾರ್ಪಟ್ಟಿರುವ ಸಾಧನಗಳೊಂದಿಗೆ ಪರಿಚಿತರಾಗಿದ್ದಾರೆ ಎಂದು ನಾವು ನಿರೀಕ್ಷಿಸಬಹುದು, ಸರಿ?

ಮೂಲಕ ಟೆಲಿಗ್ರಾಮ್-ಕ್ಲೈ ವಿಟಾಲಿ ವಾಲ್ಟ್‌ಮ್ಯಾನ್, ಅದರ (ಕ್ಲೈ) ಗಡಿಯ ಹೊರಗೆ TLO ಸ್ವರೂಪದ ಸಂಭವಿಸುವಿಕೆಯಿಂದ ತಿಳಿಯಬಹುದು, ತಂಡದ ಸದಸ್ಯ - ಈಗ TL ಪಾರ್ಸಿಂಗ್‌ಗಾಗಿ ಲೈಬ್ರರಿಯನ್ನು ನಿಯೋಜಿಸಲಾಗಿದೆ отдельно, ಅವಳ ಅನಿಸಿಕೆ ಏನು TL ಪಾರ್ಸರ್? ..

16.12 04:18 ವಾಸಿಲಿ: ಯಾರಾದರೂ ಲೆಕ್ಸ್+ಯಾಕ್ ಅನ್ನು ಕರಗತ ಮಾಡಿಕೊಳ್ಳಲಿಲ್ಲ ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ
16.12 04:18 ವಾಸಿಲಿ: ನಾನು ಅದನ್ನು ಬೇರೆ ರೀತಿಯಲ್ಲಿ ವಿವರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ
16.12 04:18 ವಾಸಿಲಿ: ಸರಿ, ಅಥವಾ VK ಯಲ್ಲಿನ ಸಾಲುಗಳ ಸಂಖ್ಯೆಗೆ ಅವರಿಗೆ ಪಾವತಿಸಲಾಗಿದೆ
16.12 04:19 ವಾಸಿಲಿ: 3k+ ಸಾಲುಗಳು ಇತ್ಯಾದಿ.<censored> ಪಾರ್ಸರ್ ಬದಲಿಗೆ

ಬಹುಶಃ ಒಂದು ವಿನಾಯಿತಿ? ಹೇಗೆ ಎಂದು ನೋಡೋಣ ಮಾಡುತ್ತದೆ ಇದು ಅಧಿಕೃತ ಕ್ಲೈಂಟ್ - ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್:

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

ಪೈಥಾನ್‌ನಲ್ಲಿ 1100+ ಸಾಲುಗಳು, ಒಂದೆರಡು ನಿಯಮಿತ ಅಭಿವ್ಯಕ್ತಿಗಳು + ವೆಕ್ಟರ್‌ನಂತಹ ವಿಶೇಷ ಪ್ರಕರಣಗಳು, ಇದು TL ಸಿಂಟ್ಯಾಕ್ಸ್‌ಗೆ ಅನುಗುಣವಾಗಿರಬೇಕು ಎಂದು ಸ್ಕೀಮ್‌ನಲ್ಲಿ ಘೋಷಿಸಲಾಗಿದೆ, ಆದರೆ ಅವರು ಅದನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಈ ಸಿಂಟ್ಯಾಕ್ಸ್ ಅನ್ನು ಅವಲಂಬಿಸಿದ್ದಾರೆ... ಪ್ರಶ್ನೆ ಉದ್ಭವಿಸುತ್ತದೆ, ಇದೆಲ್ಲವೂ ಏಕೆ ಪವಾಡ?иದಾಖಲಾತಿಗಳ ಪ್ರಕಾರ ಯಾರೂ ಅದನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಹೋಗದಿದ್ದರೆ ಅದು ಹೆಚ್ಚು ಲೇಯರ್ಡ್ ಆಗಿದೆಯೇ?!

ಅಂದಹಾಗೆ... ನಾವು CRC32 ತಪಾಸಣೆ ಕುರಿತು ಮಾತನಾಡಿದ್ದು ನೆನಪಿದೆಯೇ? ಆದ್ದರಿಂದ, ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್ ಕೋಡ್ ಜನರೇಟರ್‌ನಲ್ಲಿ CRC32 ಅನ್ನು ಲೆಕ್ಕಹಾಕಿದ ಆ ಪ್ರಕಾರಗಳಿಗೆ ವಿನಾಯಿತಿಗಳ ಪಟ್ಟಿ ಇದೆ. ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ ರೇಖಾಚಿತ್ರದಲ್ಲಿ ಸೂಚಿಸಲಾದ ಒಂದರೊಂದಿಗೆ!

ವಾಸಿಲಿ, [18.12/22 49:XNUMX] ಮತ್ತು ಇಲ್ಲಿ ನಾನು ಅಂತಹ TL ಅಗತ್ಯವಿದೆಯೇ ಎಂದು ಯೋಚಿಸುತ್ತೇನೆ
ನಾನು ಪರ್ಯಾಯ ಅಳವಡಿಕೆಗಳೊಂದಿಗೆ ಗೊಂದಲಕ್ಕೀಡಾಗಲು ಬಯಸಿದರೆ, ನಾನು ಸಾಲಿನ ವಿರಾಮಗಳನ್ನು ಸೇರಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತೇನೆ, ಅರ್ಧದಷ್ಟು ಪಾರ್ಸರ್‌ಗಳು ಬಹು-ಸಾಲಿನ ವ್ಯಾಖ್ಯಾನಗಳಲ್ಲಿ ಮುರಿಯುತ್ತವೆ
tdesktop, ಆದಾಗ್ಯೂ, ಸಹ

ಒನ್-ಲೈನರ್ ಬಗ್ಗೆ ಪಾಯಿಂಟ್ ನೆನಪಿಡಿ, ನಾವು ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಹಿಂತಿರುಗುತ್ತೇವೆ.

ಸರಿ, ಟೆಲಿಗ್ರಾಮ್-ಕ್ಲೈ ಅನಧಿಕೃತವಾಗಿದೆ, ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್ ಅಧಿಕೃತವಾಗಿದೆ, ಆದರೆ ಇತರರ ಬಗ್ಗೆ ಏನು? ಯಾರಿಗೆ ಗೊತ್ತು?.. Android ಕ್ಲೈಂಟ್ ಕೋಡ್‌ನಲ್ಲಿ ಯಾವುದೇ ಸ್ಕೀಮಾ ಪಾರ್ಸರ್ ಇರಲಿಲ್ಲ (ಇದು ಮುಕ್ತ ಮೂಲಗಳ ಬಗ್ಗೆ ಪ್ರಶ್ನೆಗಳನ್ನು ಹುಟ್ಟುಹಾಕುತ್ತದೆ, ಆದರೆ ಇದು ಎರಡನೇ ಭಾಗವಾಗಿದೆ), ಆದರೆ ಹಲವಾರು ಇತರ ತಮಾಷೆಯ ಕೋಡ್ ತುಣುಕುಗಳು ಇದ್ದವು, ಆದರೆ ಅವುಗಳಲ್ಲಿ ಹೆಚ್ಚಿನವು ಕೆಳಗಿನ ಉಪವಿಭಾಗ.

ಧಾರಾವಾಹಿ ಆಚರಣೆಯಲ್ಲಿ ಇತರ ಯಾವ ಪ್ರಶ್ನೆಗಳನ್ನು ಹುಟ್ಟುಹಾಕುತ್ತದೆ? ಉದಾಹರಣೆಗೆ, ಅವರು ಬಹಳಷ್ಟು ಕೆಲಸಗಳನ್ನು ಮಾಡಿದರು, ಸಹಜವಾಗಿ, ಬಿಟ್ ಕ್ಷೇತ್ರಗಳು ಮತ್ತು ಷರತ್ತುಬದ್ಧ ಕ್ಷೇತ್ರಗಳೊಂದಿಗೆ:

ವಾಸಿಲಿ: flags.0? true
ಕ್ಷೇತ್ರವು ಪ್ರಸ್ತುತವಾಗಿದೆ ಮತ್ತು ಧ್ವಜವನ್ನು ಹೊಂದಿಸಿದರೆ ಅದು ನಿಜವಾಗಿದೆ ಎಂದು ಅರ್ಥ

ವಾಸಿಲಿ: flags.1? int
ಕ್ಷೇತ್ರವು ಪ್ರಸ್ತುತವಾಗಿದೆ ಮತ್ತು ಅದನ್ನು ನಿರ್ಲಕ್ಷಿಸಬೇಕಾಗಿದೆ ಎಂದರ್ಥ

ವಾಸಿಲಿ: ಕತ್ತೆ, ನೀವು ಏನು ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಚಿಂತಿಸಬೇಡಿ!
ವಾಸಿಲಿ: ಸತ್ಯವು ಶೂನ್ಯ-ಉದ್ದದ ಪ್ರಕಾರವಾಗಿದೆ ಎಂದು ಡಾಕ್‌ನಲ್ಲಿ ಎಲ್ಲೋ ಉಲ್ಲೇಖವಿದೆ, ಆದರೆ ಅವರ ಡಾಕ್‌ನಿಂದ ಏನನ್ನೂ ಜೋಡಿಸುವುದು ಅಸಾಧ್ಯ
ವಾಸಿಲಿ: ಓಪನ್ ಸೋರ್ಸ್ ಅಳವಡಿಕೆಗಳಲ್ಲಿ ಇದು ಹಾಗಲ್ಲ, ಆದರೆ ಊರುಗೋಲುಗಳು ಮತ್ತು ಬೆಂಬಲಗಳ ಗುಂಪೇ ಇವೆ

ಟೆಲಿಥಾನ್ ಬಗ್ಗೆ ಏನು? MTProto ವಿಷಯದ ಮುಂದೆ ನೋಡುತ್ತಿರುವುದು, ಒಂದು ಉದಾಹರಣೆ - ದಾಖಲಾತಿಯಲ್ಲಿ ಅಂತಹ ತುಣುಕುಗಳಿವೆ, ಆದರೆ ಚಿಹ್ನೆ % ಇದನ್ನು "ನೀಡಿದ ಬೇರ್-ಟೈಪ್‌ಗೆ ಅನುಗುಣವಾಗಿ" ಎಂದು ಮಾತ್ರ ವಿವರಿಸಲಾಗಿದೆ, ಅಂದರೆ. ಕೆಳಗಿನ ಉದಾಹರಣೆಗಳಲ್ಲಿ ದೋಷವಿದೆ ಅಥವಾ ಯಾವುದೋ ದಾಖಲೆಯಿಲ್ಲ:

ವಾಸಿಲಿ, [22.06.18 18:38] ಒಂದೇ ಸ್ಥಳದಲ್ಲಿ:

msg_container#73f1f8dc messages:vector message = MessageContainer;

ವಿಭಿನ್ನವಾಗಿ:

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

ಮತ್ತು ಇವು ಎರಡು ದೊಡ್ಡ ವ್ಯತ್ಯಾಸಗಳಾಗಿವೆ, ನಿಜ ಜೀವನದಲ್ಲಿ ಕೆಲವು ರೀತಿಯ ಬೆತ್ತಲೆ ವೆಕ್ಟರ್ ಬರುತ್ತದೆ

ನಾನು ಬರಿಯ ವೆಕ್ಟರ್ ವ್ಯಾಖ್ಯಾನವನ್ನು ನೋಡಿಲ್ಲ ಮತ್ತು ಒಂದನ್ನು ನೋಡಿಲ್ಲ

ಟೆಲಿಥಾನ್‌ನಲ್ಲಿ ಕೈಯಿಂದ ವಿಶ್ಲೇಷಣೆ ಬರೆಯಲಾಗಿದೆ

ಅವರ ರೇಖಾಚಿತ್ರದಲ್ಲಿ ವ್ಯಾಖ್ಯಾನವನ್ನು ಕಾಮೆಂಟ್ ಮಾಡಲಾಗಿದೆ msg_container

ಮತ್ತೆ, ಪ್ರಶ್ನೆಯು ಶೇ. ಇದನ್ನು ವಿವರಿಸಲಾಗಿಲ್ಲ.

ವಾಡಿಮ್ ಗೊಂಚರೋವ್, [22.06.18 19:22] ಮತ್ತು tdesktop ನಲ್ಲಿ?

ವಾಸಿಲಿ, [22.06.18 19:23] ಆದರೆ ಸಾಮಾನ್ಯ ಇಂಜಿನ್‌ಗಳಲ್ಲಿ ಅವರ TL ಪಾರ್ಸರ್ ಹೆಚ್ಚಾಗಿ ಇದನ್ನು ತಿನ್ನುವುದಿಲ್ಲ

// parsed manually

TL ಒಂದು ಸುಂದರವಾದ ಅಮೂರ್ತತೆಯಾಗಿದೆ, ಯಾರೂ ಅದನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಕಾರ್ಯಗತಗೊಳಿಸುವುದಿಲ್ಲ

ಮತ್ತು % ಅವರ ಯೋಜನೆಯ ಆವೃತ್ತಿಯಲ್ಲಿಲ್ಲ

ಆದರೆ ಇಲ್ಲಿ ದಸ್ತಾವೇಜನ್ನು ಸ್ವತಃ ವಿರೋಧಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ idk

ಇದು ವ್ಯಾಕರಣದಲ್ಲಿ ಕಂಡುಬಂದಿದೆ, ಅವರು ಕೇವಲ ಶಬ್ದಾರ್ಥವನ್ನು ವಿವರಿಸಲು ಮರೆತುಬಿಡಬಹುದು

ನೀವು TL ನಲ್ಲಿ ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ನೋಡಿದ್ದೀರಿ, ಅರ್ಧ ಲೀಟರ್ ಇಲ್ಲದೆ ನೀವು ಅದನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ

"ಸರಿ, ಹೇಳೋಣ," ಇನ್ನೊಬ್ಬ ಓದುಗರು ಹೇಳುತ್ತಾರೆ, "ನೀವು ಏನನ್ನಾದರೂ ಟೀಕಿಸುತ್ತೀರಿ, ಆದ್ದರಿಂದ ಅದನ್ನು ಹೇಗೆ ಮಾಡಬೇಕೆಂದು ನನಗೆ ತೋರಿಸಿ."

ವಾಸಿಲಿ ಉತ್ತರಿಸುತ್ತಾನೆ: “ಪಾರ್ಸರ್‌ಗೆ ಸಂಬಂಧಿಸಿದಂತೆ, ನಾನು ಅಂತಹ ವಿಷಯಗಳನ್ನು ಇಷ್ಟಪಡುತ್ತೇನೆ

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

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

ಹೇಗಾದರೂ ಉತ್ತಮ ಇಷ್ಟ

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

ಅಥವಾ

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

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

ಇದು ಸಂಪೂರ್ಣ ಲೆಕ್ಸರ್ ಆಗಿದೆ:

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

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

ಆ. ಅದನ್ನು ಸ್ವಲ್ಪಮಟ್ಟಿಗೆ ಹೇಳುವುದು ಸರಳವಾಗಿದೆ."

ಸಾಮಾನ್ಯವಾಗಿ, ಪರಿಣಾಮವಾಗಿ, ವಾಸ್ತವವಾಗಿ ಬಳಸಿದ TL ಉಪವಿಭಾಗಕ್ಕಾಗಿ ಪಾರ್ಸರ್ ಮತ್ತು ಕೋಡ್ ಜನರೇಟರ್ ಸರಿಸುಮಾರು 100 ಸಾಲುಗಳ ವ್ಯಾಕರಣ ಮತ್ತು ~ 300 ಲೈನ್‌ಗಳ ಜನರೇಟರ್‌ಗೆ ಹೊಂದಿಕೊಳ್ಳುತ್ತದೆ (ಎಲ್ಲವನ್ನೂ ಎಣಿಸುವುದು printನ ರಚಿತವಾದ ಕೋಡ್), ಪ್ರತಿ ತರಗತಿಯಲ್ಲಿ ಆತ್ಮಾವಲೋಕನಕ್ಕಾಗಿ ಟೈಪ್ ಮಾಹಿತಿ ಬನ್‌ಗಳು ಸೇರಿದಂತೆ. ಪ್ರತಿಯೊಂದು ಪಾಲಿಮಾರ್ಫಿಕ್ ಪ್ರಕಾರವು ಖಾಲಿ ಅಮೂರ್ತ ಮೂಲ ವರ್ಗವಾಗಿ ಬದಲಾಗುತ್ತದೆ, ಮತ್ತು ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್‌ಗಳು ಅದರಿಂದ ಆನುವಂಶಿಕವಾಗಿ ಪಡೆಯುತ್ತಾರೆ ಮತ್ತು ಧಾರಾವಾಹಿ ಮತ್ತು ಡೀಸರಲೈಸೇಶನ್ ವಿಧಾನಗಳನ್ನು ಹೊಂದಿದ್ದಾರೆ.

ಪ್ರಕಾರದ ಭಾಷೆಯಲ್ಲಿ ಪ್ರಕಾರಗಳ ಕೊರತೆ

ಬಲವಾದ ಟೈಪಿಂಗ್ ಒಳ್ಳೆಯದು, ಸರಿ? ಇಲ್ಲ, ಇದು ಹೋಲಿವರ್ ಅಲ್ಲ (ಆದರೂ ನಾನು ಡೈನಾಮಿಕ್ ಭಾಷೆಗಳಿಗೆ ಆದ್ಯತೆ ನೀಡುತ್ತೇನೆ), ಆದರೆ TL ನ ಚೌಕಟ್ಟಿನೊಳಗೆ ಒಂದು ನಿಲುವು. ಅದರ ಆಧಾರದ ಮೇಲೆ, ಭಾಷೆ ನಮಗೆ ಎಲ್ಲಾ ರೀತಿಯ ಚೆಕ್ಗಳನ್ನು ಒದಗಿಸಬೇಕು. ಸರಿ, ಸರಿ, ಬಹುಶಃ ಅವನೇ ಅಲ್ಲ, ಆದರೆ ಅನುಷ್ಠಾನ, ಆದರೆ ಅವನು ಕನಿಷ್ಠ ಅವುಗಳನ್ನು ವಿವರಿಸಬೇಕು. ಮತ್ತು ನಾವು ಯಾವ ರೀತಿಯ ಅವಕಾಶಗಳನ್ನು ಬಯಸುತ್ತೇವೆ?

ಮೊದಲನೆಯದಾಗಿ, ನಿರ್ಬಂಧಗಳು. ಫೈಲ್‌ಗಳನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ನಾವು ದಸ್ತಾವೇಜನ್ನು ಇಲ್ಲಿ ನೋಡುತ್ತೇವೆ:

ಫೈಲ್‌ನ ಬೈನರಿ ವಿಷಯವನ್ನು ನಂತರ ಭಾಗಗಳಾಗಿ ವಿಭಜಿಸಲಾಗುತ್ತದೆ. ಎಲ್ಲಾ ಭಾಗಗಳು ಒಂದೇ ಗಾತ್ರವನ್ನು ಹೊಂದಿರಬೇಕು ( ಭಾಗ_ಗಾತ್ರ ) ಮತ್ತು ಕೆಳಗಿನ ಷರತ್ತುಗಳನ್ನು ಪೂರೈಸಬೇಕು:

  • part_size % 1024 = 0 (1KB ಯಿಂದ ಭಾಗಿಸಬಹುದು)
  • 524288 % part_size = 0 (512KB ಭಾಗ_ಗಾತ್ರದಿಂದ ಸಮವಾಗಿ ಭಾಗಿಸಬೇಕು)

ಕೊನೆಯ ಭಾಗವು ಈ ಷರತ್ತುಗಳನ್ನು ಪೂರೈಸಬೇಕಾಗಿಲ್ಲ, ಅದರ ಗಾತ್ರ ಭಾಗ_ಗಾತ್ರಕ್ಕಿಂತ ಕಡಿಮೆಯಿರುತ್ತದೆ.

ಪ್ರತಿಯೊಂದು ಭಾಗವು ಅನುಕ್ರಮ ಸಂಖ್ಯೆಯನ್ನು ಹೊಂದಿರಬೇಕು, ಫೈಲ್_ಭಾಗ0 ರಿಂದ 2,999 ರವರೆಗಿನ ಮೌಲ್ಯದೊಂದಿಗೆ.

ಫೈಲ್ ಅನ್ನು ವಿಭಜಿಸಿದ ನಂತರ ನೀವು ಅದನ್ನು ಸರ್ವರ್‌ನಲ್ಲಿ ಉಳಿಸುವ ವಿಧಾನವನ್ನು ಆರಿಸಬೇಕಾಗುತ್ತದೆ. ಬಳಸಿ upload.saveBigFilePart ಫೈಲ್‌ನ ಪೂರ್ಣ ಗಾತ್ರವು 10 MB ಗಿಂತ ಹೆಚ್ಚಿದ್ದರೆ ಮತ್ತು upload.saveFilePart ಸಣ್ಣ ಫೈಲ್‌ಗಳಿಗಾಗಿ.
[…] ಕೆಳಗಿನ ಡೇಟಾ ಇನ್‌ಪುಟ್ ದೋಷಗಳಲ್ಲಿ ಒಂದನ್ನು ಹಿಂತಿರುಗಿಸಬಹುದು:

  • FILE_PARTS_INVALID — ಭಾಗಗಳ ಅಮಾನ್ಯ ಸಂಖ್ಯೆ. ಮೌಲ್ಯವು ನಡುವೆ ಇಲ್ಲ 1..3000

ರೇಖಾಚಿತ್ರದಲ್ಲಿ ಇವುಗಳಲ್ಲಿ ಯಾವುದಾದರೂ ಇದೆಯೇ? ಇದು ಹೇಗಾದರೂ TL ಬಳಸಿಕೊಂಡು ವ್ಯಕ್ತಪಡಿಸಬಹುದೇ? ಸಂ. ಆದರೆ ಕ್ಷಮಿಸಿ, ಅಜ್ಜನ ಟರ್ಬೊ ಪ್ಯಾಸ್ಕಲ್ ಸಹ ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಪ್ರಕಾರಗಳನ್ನು ವಿವರಿಸಲು ಸಾಧ್ಯವಾಯಿತು ಶ್ರೇಣಿಗಳು. ಮತ್ತು ಅವನಿಗೆ ಇನ್ನೂ ಒಂದು ವಿಷಯ ತಿಳಿದಿತ್ತು, ಈಗ ಅದನ್ನು ಚೆನ್ನಾಗಿ ಕರೆಯಲಾಗುತ್ತದೆ enum - ಸ್ಥಿರ (ಸಣ್ಣ) ಸಂಖ್ಯೆಯ ಮೌಲ್ಯಗಳ ಎಣಿಕೆಯನ್ನು ಒಳಗೊಂಡಿರುವ ಒಂದು ವಿಧ. ಸಿ - ಸಂಖ್ಯಾಶಾಸ್ತ್ರದಂತಹ ಭಾಷೆಗಳಲ್ಲಿ, ಇಲ್ಲಿಯವರೆಗೆ ನಾವು ಪ್ರಕಾರಗಳ ಬಗ್ಗೆ ಮಾತ್ರ ಮಾತನಾಡಿದ್ದೇವೆ ಎಂಬುದನ್ನು ಗಮನಿಸಿ ಸಂಖ್ಯೆಗಳು. ಆದರೆ ಅರೇಗಳು, ಸ್ಟ್ರಿಂಗ್‌ಗಳು ಸಹ ಇವೆ ... ಉದಾಹರಣೆಗೆ, ಈ ಸ್ಟ್ರಿಂಗ್ ಫೋನ್ ಸಂಖ್ಯೆಯನ್ನು ಮಾತ್ರ ಹೊಂದಿರಬಹುದು ಎಂದು ವಿವರಿಸಲು ಚೆನ್ನಾಗಿರುತ್ತದೆ, ಸರಿ?

ಇದ್ಯಾವುದೂ TL ನಲ್ಲಿಲ್ಲ. ಆದರೆ, ಉದಾಹರಣೆಗೆ, JSON ಸ್ಕೀಮಾದಲ್ಲಿ ಇದೆ. ಮತ್ತು ಯಾರಾದರೂ 512 KB ಯ ವಿಭಜನೆಯ ಬಗ್ಗೆ ವಾದಿಸಿದರೆ, ಇದನ್ನು ಇನ್ನೂ ಕೋಡ್‌ನಲ್ಲಿ ಪರಿಶೀಲಿಸಬೇಕಾಗಿದೆ, ನಂತರ ಕ್ಲೈಂಟ್ ಸರಳವಾಗಿ ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ ನನಗೆ ಸಾಧ್ಯವಾಗಲಿಲ್ಲ ವ್ಯಾಪ್ತಿಯ ಹೊರಗೆ ಸಂಖ್ಯೆಯನ್ನು ಕಳುಹಿಸಿ 1..3000 (ಮತ್ತು ಅನುಗುಣವಾದ ದೋಷವು ಉದ್ಭವಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ) ಅದು ಸಾಧ್ಯವಿತ್ತು, ಸರಿ? ..

ಮೂಲಕ, ದೋಷಗಳು ಮತ್ತು ರಿಟರ್ನ್ ಮೌಲ್ಯಗಳ ಬಗ್ಗೆ. ಟಿಎಲ್‌ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಿದವರು ಸಹ ತಮ್ಮ ಕಣ್ಣುಗಳನ್ನು ಮಸುಕುಗೊಳಿಸುತ್ತಾರೆ - ಅದು ನಮಗೆ ತಕ್ಷಣ ಹೊಳೆಯಲಿಲ್ಲ ಪ್ರತಿಯೊಂದೂ TL ನಲ್ಲಿನ ಕಾರ್ಯವು ವಾಸ್ತವವಾಗಿ ವಿವರಿಸಿದ ರಿಟರ್ನ್ ಪ್ರಕಾರವನ್ನು ಮಾತ್ರವಲ್ಲದೆ ದೋಷವನ್ನೂ ಸಹ ಹಿಂತಿರುಗಿಸುತ್ತದೆ. ಆದರೆ TL ಅನ್ನು ಬಳಸಿಕೊಂಡು ಇದನ್ನು ಯಾವುದೇ ರೀತಿಯಲ್ಲಿ ಕಳೆಯಲಾಗುವುದಿಲ್ಲ. ಸಹಜವಾಗಿ, ಇದು ಈಗಾಗಲೇ ಸ್ಪಷ್ಟವಾಗಿದೆ ಮತ್ತು ಪ್ರಾಯೋಗಿಕವಾಗಿ ಯಾವುದಕ್ಕೂ ಅಗತ್ಯವಿಲ್ಲ (ವಾಸ್ತವವಾಗಿ, ಆರ್‌ಪಿಸಿಯನ್ನು ವಿಭಿನ್ನ ರೀತಿಯಲ್ಲಿ ಮಾಡಬಹುದು, ನಾವು ನಂತರ ಇದಕ್ಕೆ ಹಿಂತಿರುಗುತ್ತೇವೆ) - ಆದರೆ ಅಮೂರ್ತ ಪ್ರಕಾರಗಳ ಗಣಿತದ ಪರಿಕಲ್ಪನೆಗಳ ಶುದ್ಧತೆಯ ಬಗ್ಗೆ ಏನು ಸ್ವರ್ಗೀಯ ಪ್ರಪಂಚದಿಂದ?.. ನಾನು ಟಗ್ ಅನ್ನು ಎತ್ತಿದ್ದೇನೆ - ಆದ್ದರಿಂದ ಅದನ್ನು ಹೊಂದಿಸಿ.

ಮತ್ತು ಅಂತಿಮವಾಗಿ, ಓದುವಿಕೆಯ ಬಗ್ಗೆ ಏನು? ಸರಿ, ಅಲ್ಲಿ, ಸಾಮಾನ್ಯವಾಗಿ, ನಾನು ಬಯಸುತ್ತೇನೆ ವಿವರಣೆ ಇದು ಸ್ಕೀಮಾದಲ್ಲಿ ಸರಿಯಾಗಿದೆಯೇ (JSON ಸ್ಕೀಮಾದಲ್ಲಿ, ಮತ್ತೊಮ್ಮೆ, ಅದು), ಆದರೆ ನೀವು ಈಗಾಗಲೇ ಅದರೊಂದಿಗೆ ಆಯಾಸಗೊಂಡಿದ್ದರೆ, ಪ್ರಾಯೋಗಿಕ ಭಾಗದ ಬಗ್ಗೆ ಏನು - ಕನಿಷ್ಠ ನವೀಕರಣಗಳ ಸಮಯದಲ್ಲಿ ವ್ಯತ್ಯಾಸಗಳನ್ನು ಕ್ಷುಲ್ಲಕವಾಗಿ ನೋಡುವುದು? ನಲ್ಲಿ ನೀವೇ ನೋಡಿ ನಿಜವಾದ ಉದಾಹರಣೆಗಳು:

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

ಅಥವಾ

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

ಇದು ಪ್ರತಿಯೊಬ್ಬರ ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿದೆ, ಆದರೆ GitHub, ಉದಾಹರಣೆಗೆ, ಅಂತಹ ದೀರ್ಘ ರೇಖೆಗಳ ಒಳಗೆ ಬದಲಾವಣೆಗಳನ್ನು ಹೈಲೈಟ್ ಮಾಡಲು ನಿರಾಕರಿಸುತ್ತದೆ. ಆಟವು "10 ವ್ಯತ್ಯಾಸಗಳನ್ನು ಹುಡುಕಿ", ಮತ್ತು ಮೆದುಳು ತಕ್ಷಣವೇ ನೋಡುವುದು ಎಂದರೆ ಎರಡೂ ಉದಾಹರಣೆಗಳಲ್ಲಿ ಪ್ರಾರಂಭ ಮತ್ತು ಅಂತ್ಯಗಳು ಒಂದೇ ಆಗಿರುತ್ತವೆ, ನೀವು ಮಧ್ಯದಲ್ಲಿ ಎಲ್ಲೋ ಬೇಸರದಿಂದ ಓದಬೇಕಾಗಿದೆ ... ನನ್ನ ಅಭಿಪ್ರಾಯದಲ್ಲಿ, ಇದು ಕೇವಲ ಸಿದ್ಧಾಂತದಲ್ಲಿ ಅಲ್ಲ, ಆದರೆ ಸಂಪೂರ್ಣವಾಗಿ ದೃಷ್ಟಿಗೋಚರವಾಗಿ ಕೊಳಕು ಮತ್ತು ಕೊಳಕು.

ಮೂಲಕ, ಸಿದ್ಧಾಂತದ ಶುದ್ಧತೆಯ ಬಗ್ಗೆ. ನಮಗೆ ಬಿಟ್ ಕ್ಷೇತ್ರಗಳು ಏಕೆ ಬೇಕು? ಅವರು ಎಂದು ತೋರುತ್ತದೆ ಅಲ್ಲವೇ ವಾಸನೆ ಪ್ರಕಾರದ ಸಿದ್ಧಾಂತದ ದೃಷ್ಟಿಕೋನದಿಂದ ಕೆಟ್ಟದ್ದೇ? ವಿವರಣೆಯನ್ನು ರೇಖಾಚಿತ್ರದ ಹಿಂದಿನ ಆವೃತ್ತಿಗಳಲ್ಲಿ ಕಾಣಬಹುದು. ಮೊದಲಿಗೆ, ಹೌದು, ಅದು ಹೇಗೆ, ಪ್ರತಿ ಸೀನುವಿಕೆಗೆ ಹೊಸ ಪ್ರಕಾರವನ್ನು ರಚಿಸಲಾಗಿದೆ. ಈ ಮೂಲಗಳು ಇನ್ನೂ ಈ ರೂಪದಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿವೆ, ಉದಾಹರಣೆಗೆ:

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

ಆದರೆ ಈಗ ಊಹಿಸಿ, ನಿಮ್ಮ ರಚನೆಯಲ್ಲಿ ನೀವು 5 ಐಚ್ಛಿಕ ಕ್ಷೇತ್ರಗಳನ್ನು ಹೊಂದಿದ್ದರೆ, ನಂತರ ಎಲ್ಲಾ ಸಂಭಾವ್ಯ ಆಯ್ಕೆಗಳಿಗಾಗಿ ನಿಮಗೆ 32 ಪ್ರಕಾರಗಳು ಬೇಕಾಗುತ್ತವೆ. ಸಂಯೋಜಿತ ಸ್ಫೋಟ. ಹೀಗಾಗಿ, TL ಸಿದ್ಧಾಂತದ ಸ್ಫಟಿಕ ಶುದ್ಧತೆಯು ಮತ್ತೊಮ್ಮೆ ಧಾರಾವಾಹಿಯ ಕಠೋರ ವಾಸ್ತವತೆಯ ಎರಕಹೊಯ್ದ ಕಬ್ಬಿಣದ ಕತ್ತೆಯ ವಿರುದ್ಧ ಛಿದ್ರವಾಯಿತು.

ಹೆಚ್ಚುವರಿಯಾಗಿ, ಕೆಲವು ಸ್ಥಳಗಳಲ್ಲಿ ಈ ವ್ಯಕ್ತಿಗಳು ತಮ್ಮದೇ ಆದ ಟೈಪೊಲಾಜಿಯನ್ನು ಉಲ್ಲಂಘಿಸುತ್ತಾರೆ. ಉದಾಹರಣೆಗೆ, MTProto (ಮುಂದಿನ ಅಧ್ಯಾಯ) ನಲ್ಲಿ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು Gzip ನಿಂದ ಸಂಕುಚಿತಗೊಳಿಸಬಹುದು, ಎಲ್ಲವೂ ಉತ್ತಮವಾಗಿದೆ - ಪದರಗಳು ಮತ್ತು ಸರ್ಕ್ಯೂಟ್ ಅನ್ನು ಉಲ್ಲಂಘಿಸಿರುವುದನ್ನು ಹೊರತುಪಡಿಸಿ. ಮತ್ತೊಮ್ಮೆ, RpcResult ಸ್ವತಃ ಕೊಯ್ಲು ಮಾಡಲಾಗಿಲ್ಲ, ಆದರೆ ಅದರ ವಿಷಯಗಳು. ಸರಿ, ಇದನ್ನು ಏಕೆ ಮಾಡಬೇಕು?.. ಸಂಕೋಚನವು ಎಲ್ಲಿಯಾದರೂ ಕೆಲಸ ಮಾಡಲು ನಾನು ಊರುಗೋಲನ್ನು ಕತ್ತರಿಸಬೇಕಾಗಿತ್ತು.

ಅಥವಾ ಇನ್ನೊಂದು ಉದಾಹರಣೆ, ನಾವು ಒಮ್ಮೆ ದೋಷವನ್ನು ಕಂಡುಹಿಡಿದಿದ್ದೇವೆ - ಅದನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ InputPeerUser вместо InputUser. ಅಥವಾ ಪ್ರತಿಯಾಗಿ. ಆದರೆ ಅದು ಕೆಲಸ ಮಾಡಿದೆ! ಅಂದರೆ, ಸರ್ವರ್ ಪ್ರಕಾರದ ಬಗ್ಗೆ ಕಾಳಜಿ ವಹಿಸಲಿಲ್ಲ. ಇದು ಹೇಗೆ ಸಾಧ್ಯ? ಟೆಲಿಗ್ರಾಮ್-ಕ್ಲೈನಿಂದ ಕೋಡ್ ತುಣುಕುಗಳ ಮೂಲಕ ಉತ್ತರವನ್ನು ನಮಗೆ ನೀಡಬಹುದು:

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

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

ಬೇರೆ ರೀತಿಯಲ್ಲಿ ಹೇಳುವುದಾದರೆ, ಇಲ್ಲಿ ಧಾರಾವಾಹಿಯನ್ನು ಮಾಡಲಾಗುತ್ತದೆ ಹಸ್ತಚಾಲಿತವಾಗಿ, ಕೋಡ್ ರಚಿಸಲಾಗಿಲ್ಲ! ಬಹುಶಃ ಸರ್ವರ್ ಅನ್ನು ಇದೇ ರೀತಿಯಲ್ಲಿ ಅಳವಡಿಸಲಾಗಿದೆಯೇ?.. ತಾತ್ವಿಕವಾಗಿ, ಒಮ್ಮೆ ಮಾಡಿದರೆ ಇದು ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ ನವೀಕರಣಗಳ ಸಮಯದಲ್ಲಿ ನಂತರ ಅದನ್ನು ಹೇಗೆ ಬೆಂಬಲಿಸಬಹುದು? ಇದಕ್ಕಾಗಿಯೇ ಯೋಜನೆಯನ್ನು ಕಂಡುಹಿಡಿಯಲಾಗಿದೆಯೇ? ಮತ್ತು ಇಲ್ಲಿ ನಾವು ಮುಂದಿನ ಪ್ರಶ್ನೆಗೆ ಹೋಗುತ್ತೇವೆ.

ಆವೃತ್ತಿ. ಪದರಗಳು

ಸ್ಕೀಮ್ಯಾಟಿಕ್ ಆವೃತ್ತಿಗಳನ್ನು ಏಕೆ ಲೇಯರ್‌ಗಳು ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ ಎಂಬುದನ್ನು ಪ್ರಕಟಿಸಿದ ಸ್ಕೀಮ್ಯಾಟಿಕ್‌ಗಳ ಇತಿಹಾಸದ ಆಧಾರದ ಮೇಲೆ ಮಾತ್ರ ಊಹಿಸಬಹುದು. ಸ್ಪಷ್ಟವಾಗಿ, ಮೊದಲಿಗೆ ಲೇಖಕರು ಬದಲಾಗದ ಸ್ಕೀಮ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಮೂಲಭೂತ ವಿಷಯಗಳನ್ನು ಮಾಡಬಹುದು ಎಂದು ಭಾವಿಸಿದ್ದರು, ಮತ್ತು ಅಗತ್ಯವಿರುವಲ್ಲಿ ಮಾತ್ರ, ನಿರ್ದಿಷ್ಟ ವಿನಂತಿಗಳಿಗಾಗಿ, ಅವರು ಬೇರೆ ಆವೃತ್ತಿಯನ್ನು ಬಳಸುತ್ತಿದ್ದಾರೆ ಎಂದು ಸೂಚಿಸುತ್ತಾರೆ. ತಾತ್ವಿಕವಾಗಿ, ಇದು ಕೆಟ್ಟ ಕಲ್ಪನೆಯಲ್ಲದಿದ್ದರೂ ಸಹ, ಹೊಸದು "ಮಿಶ್ರಣ" ಆಗಿರುತ್ತದೆ, ಅದು ಹಳೆಯದಾದ ಮೇಲೆ ಲೇಯರ್ಡ್ ಆಗಿರುತ್ತದೆ. ಆದರೆ ಅದನ್ನು ಹೇಗೆ ಮಾಡಲಾಯಿತು ಎಂದು ನೋಡೋಣ. ನಿಜ, ನಾನು ಅದನ್ನು ಮೊದಲಿನಿಂದಲೂ ನೋಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ - ಇದು ತಮಾಷೆಯಾಗಿದೆ, ಆದರೆ ಮೂಲ ಪದರದ ರೇಖಾಚಿತ್ರವು ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ. ಲೇಯರ್‌ಗಳು 2 ರಿಂದ ಪ್ರಾರಂಭವಾಯಿತು. ದಸ್ತಾವೇಜನ್ನು ವಿಶೇಷ TL ವೈಶಿಷ್ಟ್ಯದ ಬಗ್ಗೆ ನಮಗೆ ಹೇಳುತ್ತದೆ:

ಕ್ಲೈಂಟ್ ಲೇಯರ್ 2 ಅನ್ನು ಬೆಂಬಲಿಸಿದರೆ, ನಂತರ ಕೆಳಗಿನ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಅನ್ನು ಬಳಸಬೇಕು:

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

ಪ್ರಾಯೋಗಿಕವಾಗಿ, ಇದರರ್ಥ ಪ್ರತಿ API ಕರೆಗೆ ಮೊದಲು, ಮೌಲ್ಯದೊಂದಿಗೆ ಒಂದು ಇಂಟ್ 0x289dd1f6 ವಿಧಾನ ಸಂಖ್ಯೆಯ ಮೊದಲು ಸೇರಿಸಬೇಕು.

ಸಾಮಾನ್ಯವಾಗಿ ಧ್ವನಿಸುತ್ತದೆ. ಆದರೆ ಮುಂದೆ ಏನಾಯಿತು? ನಂತರ ಕಾಣಿಸಿಕೊಂಡರು

invokeWithLayer3#b7475268 query:!X = X;

ಹಾಗಾದರೆ ಮುಂದೇನು? ನೀವು ಊಹಿಸಿದಂತೆ,

invokeWithLayer4#dea0d430 query:!X = X;

ತಮಾಷೆಯೇ? ಇಲ್ಲ, ನಗುವುದು ತುಂಬಾ ಮುಂಚೆಯೇ, ಅದರ ಬಗ್ಗೆ ಯೋಚಿಸಿ ಪ್ರತಿ ಮತ್ತೊಂದು ಪದರದಿಂದ ವಿನಂತಿಯನ್ನು ಅಂತಹ ವಿಶೇಷ ಪ್ರಕಾರದಲ್ಲಿ ಸುತ್ತುವ ಅಗತ್ಯವಿದೆ - ಅವೆಲ್ಲವೂ ನಿಮಗೆ ವಿಭಿನ್ನವಾಗಿದ್ದರೆ, ನೀವು ಅವುಗಳನ್ನು ಬೇರೆ ಹೇಗೆ ಪ್ರತ್ಯೇಕಿಸಬಹುದು? ಮತ್ತು ಮುಂದೆ ಕೇವಲ 4 ಬೈಟ್‌ಗಳನ್ನು ಸೇರಿಸುವುದು ಸಾಕಷ್ಟು ಪರಿಣಾಮಕಾರಿ ವಿಧಾನವಾಗಿದೆ. ಆದ್ದರಿಂದ,

invokeWithLayer5#417a57ae query:!X = X;

ಆದರೆ ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಇದು ಒಂದು ರೀತಿಯ ಬಚನಾಲಿಯಾ ಆಗುತ್ತದೆ ಎಂಬುದು ಸ್ಪಷ್ಟವಾಗಿದೆ. ಮತ್ತು ಪರಿಹಾರವು ಬಂದಿತು:

ನವೀಕರಿಸಿ: ಲೇಯರ್ 9, ಸಹಾಯಕ ವಿಧಾನಗಳಿಂದ ಪ್ರಾರಂಭಿಸಿ invokeWithLayerN ಜೊತೆಯಲ್ಲಿ ಮಾತ್ರ ಬಳಸಬಹುದು initConnection

ಹುರ್ರೇ! 9 ಆವೃತ್ತಿಗಳ ನಂತರ, ನಾವು ಅಂತಿಮವಾಗಿ 80 ರ ದಶಕದಲ್ಲಿ ಇಂಟರ್ನೆಟ್ ಪ್ರೋಟೋಕಾಲ್‌ಗಳಲ್ಲಿ ಏನು ಮಾಡಿದ್ದೇವೆ ಎಂಬುದಕ್ಕೆ ಬಂದಿದ್ದೇವೆ - ಸಂಪರ್ಕದ ಆರಂಭದಲ್ಲಿ ಒಮ್ಮೆ ಆವೃತ್ತಿಯನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೇವೆ!

ಹಾಗಾದರೆ ಮುಂದೇನು? ..

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

ಆದರೆ ಈಗ ನೀವು ಇನ್ನೂ ನಗಬಹುದು. ಮತ್ತೊಂದು 9 ಲೇಯರ್‌ಗಳ ನಂತರ, ಆವೃತ್ತಿ ಸಂಖ್ಯೆಯನ್ನು ಹೊಂದಿರುವ ಸಾರ್ವತ್ರಿಕ ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಅನ್ನು ಅಂತಿಮವಾಗಿ ಸೇರಿಸಲಾಯಿತು, ಅದನ್ನು ಸಂಪರ್ಕದ ಪ್ರಾರಂಭದಲ್ಲಿ ಒಮ್ಮೆ ಮಾತ್ರ ಕರೆಯಬೇಕಾಗುತ್ತದೆ, ಮತ್ತು ಪದರಗಳ ಅರ್ಥವು ಕಣ್ಮರೆಯಾಗಿದೆ ಎಂದು ತೋರುತ್ತದೆ, ಈಗ ಇದು ಕೇವಲ ಷರತ್ತುಬದ್ಧ ಆವೃತ್ತಿಯಾಗಿದೆ. ಎಲ್ಲೆಲ್ಲೂ ಬೇರೆ. ಸಮಸ್ಯೆ ಪರಿಹಾರವಾಯಿತು.

ನಿಖರವಾಗಿ? ..

ವಾಸಿಲಿ, [16.07.18 14:01] ಶುಕ್ರವಾರ ಕೂಡ ನಾನು ಯೋಚಿಸಿದೆ:
ಟೆಲಿಸರ್ವರ್ ವಿನಂತಿಯಿಲ್ಲದೆ ಈವೆಂಟ್‌ಗಳನ್ನು ಕಳುಹಿಸುತ್ತದೆ. ವಿನಂತಿಗಳನ್ನು InvokeWithLayer ನಲ್ಲಿ ಸುತ್ತಿಡಬೇಕು. ಸರ್ವರ್ ನವೀಕರಣಗಳನ್ನು ಸುತ್ತುವುದಿಲ್ಲ; ಪ್ರತಿಕ್ರಿಯೆಗಳು ಮತ್ತು ನವೀಕರಣಗಳನ್ನು ಸುತ್ತುವ ಯಾವುದೇ ರಚನೆಯಿಲ್ಲ.

ಆ. ಕ್ಲೈಂಟ್ ಅವರು ನವೀಕರಣಗಳನ್ನು ಬಯಸುವ ಲೇಯರ್ ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ

ವಾಡಿಮ್ ಗೊಂಚರೋವ್, [16.07.18 14:02] InvokeWithLayer ತಾತ್ವಿಕವಾಗಿ ಊರುಗೋಲು ಅಲ್ಲವೇ?

Vasily, [16.07.18 14:02] ಇದು ಏಕೈಕ ಮಾರ್ಗವಾಗಿದೆ

ವಾಡಿಮ್ ಗೊಂಚರೋವ್, [16.07.18 14:02] ಅಂದರೆ ಅಧಿವೇಶನದ ಆರಂಭದಲ್ಲಿ ಪದರವನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುವುದು

ಮೂಲಕ, ಕ್ಲೈಂಟ್ ಡೌನ್‌ಗ್ರೇಡ್ ಅನ್ನು ಒದಗಿಸಲಾಗಿಲ್ಲ ಎಂದು ಅದು ಅನುಸರಿಸುತ್ತದೆ

ನವೀಕರಣಗಳು, ಅಂದರೆ. ಮಾದರಿ 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 ಅನಿರೀಕ್ಷಿತ ಟೈಪ್ ಐಡಿ #b5223b0f MTPMessageMedia ನಲ್ಲಿ ಓದಿದೆ…

ಟೆಲಿಗ್ರಾಮ್‌ನ ಪ್ರೋಟೋಕಾಲ್ ಮತ್ತು ಸಾಂಸ್ಥಿಕ ವಿಧಾನಗಳ ಟೀಕೆ. ಭಾಗ 1, ತಾಂತ್ರಿಕ: ಮೊದಲಿನಿಂದ ಕ್ಲೈಂಟ್ ಬರೆಯುವ ಅನುಭವ - TL, MT

ಅನಧಿಕೃತ ಕ್ಲೈಂಟ್‌ಗಳಲ್ಲಿ ಒಬ್ಬರಿಗೆ ಇದೇ ರೀತಿಯ ಸಮಸ್ಯೆ ಈಗಾಗಲೇ ಸಂಭವಿಸಿದೆ ಎಂದು ಗೂಗಲ್ ತೋರಿಸಿದೆ, ಆದರೆ ನಂತರ ಆವೃತ್ತಿ ಸಂಖ್ಯೆಗಳು ಮತ್ತು ಅದರ ಪ್ರಕಾರ, ಊಹೆಗಳು ವಿಭಿನ್ನವಾಗಿವೆ ...

ಹಾಗಾದರೆ ನಾವೇನು ​​ಮಾಡಬೇಕು? ವಾಸಿಲಿ ಮತ್ತು ನಾನು ಬೇರ್ಪಟ್ಟಿದ್ದೇವೆ: ಅವರು ಸರ್ಕ್ಯೂಟ್ ಅನ್ನು 91 ಕ್ಕೆ ನವೀಕರಿಸಲು ಪ್ರಯತ್ನಿಸಿದರು, ನಾನು ಕೆಲವು ದಿನ ಕಾಯಲು ಮತ್ತು 73 ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಲು ನಿರ್ಧರಿಸಿದೆ. ಎರಡೂ ವಿಧಾನಗಳು ಕಾರ್ಯನಿರ್ವಹಿಸಿದವು, ಆದರೆ ಅವು ಪ್ರಾಯೋಗಿಕವಾಗಿರುವುದರಿಂದ, ನಿಮಗೆ ಎಷ್ಟು ಆವೃತ್ತಿಗಳು ಮೇಲಕ್ಕೆ ಅಥವಾ ಕೆಳಕ್ಕೆ ಬೇಕು ಎಂಬುದರ ಕುರಿತು ಯಾವುದೇ ತಿಳುವಳಿಕೆ ಇಲ್ಲ. ನೆಗೆಯಲು, ಅಥವಾ ನೀವು ಎಷ್ಟು ಸಮಯ ಕಾಯಬೇಕು .

ನಂತರ ನಾನು ಪರಿಸ್ಥಿತಿಯನ್ನು ಪುನರುತ್ಪಾದಿಸಲು ಸಾಧ್ಯವಾಯಿತು: ನಾವು ಕ್ಲೈಂಟ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ, ಅದನ್ನು ಆಫ್ ಮಾಡಿ, ಸರ್ಕ್ಯೂಟ್ ಅನ್ನು ಮತ್ತೊಂದು ಪದರಕ್ಕೆ ಮರುಸಂಕಲಿಸಿ, ಮರುಪ್ರಾರಂಭಿಸಿ, ಸಮಸ್ಯೆಯನ್ನು ಮತ್ತೆ ಹಿಡಿಯಿರಿ, ಹಿಂದಿನದಕ್ಕೆ ಹಿಂತಿರುಗಿ - ಓಹ್, ಯಾವುದೇ ಸರ್ಕ್ಯೂಟ್ ಸ್ವಿಚಿಂಗ್ ಮತ್ತು ಕ್ಲೈಂಟ್ ಮರುಪ್ರಾರಂಭಿಸುವುದಿಲ್ಲ ಕೆಲವು ನಿಮಿಷಗಳು ಸಹಾಯ ಮಾಡುತ್ತವೆ. ನೀವು ವಿವಿಧ ಲೇಯರ್‌ಗಳಿಂದ ಡೇಟಾ ರಚನೆಗಳ ಮಿಶ್ರಣವನ್ನು ಸ್ವೀಕರಿಸುತ್ತೀರಿ.

ವಿವರಣೆ? ವಿವಿಧ ಪರೋಕ್ಷ ಲಕ್ಷಣಗಳಿಂದ ನೀವು ಊಹಿಸಬಹುದಾದಂತೆ, ಸರ್ವರ್ ವಿವಿಧ ಯಂತ್ರಗಳಲ್ಲಿ ವಿವಿಧ ರೀತಿಯ ಅನೇಕ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ಒಳಗೊಂಡಿದೆ. ಹೆಚ್ಚಾಗಿ, "ಬಫರಿಂಗ್" ಗೆ ಜವಾಬ್ದಾರರಾಗಿರುವ ಸರ್ವರ್ ಅದರ ಮೇಲಧಿಕಾರಿಗಳು ಕೊಟ್ಟದ್ದನ್ನು ಸರದಿಯಲ್ಲಿ ಹಾಕುತ್ತಾರೆ ಮತ್ತು ಅವರು ಅದನ್ನು ಪೀಳಿಗೆಯ ಸಮಯದಲ್ಲಿ ಜಾರಿಯಲ್ಲಿದ್ದ ಯೋಜನೆಯಲ್ಲಿ ನೀಡಿದರು. ಮತ್ತು ಈ ಕ್ಯೂ "ಕೊಳೆತ" ರವರೆಗೆ, ಅದರ ಬಗ್ಗೆ ಏನನ್ನೂ ಮಾಡಲಾಗುವುದಿಲ್ಲ.

ಬಹುಶಃ ... ಆದರೆ ಇದು ಭಯಾನಕ ಊರುಗೋಲು?!.. ಇಲ್ಲ, ಹುಚ್ಚು ಕಲ್ಪನೆಗಳ ಬಗ್ಗೆ ಯೋಚಿಸುವ ಮೊದಲು, ಅಧಿಕೃತ ಗ್ರಾಹಕರ ಕೋಡ್ ಅನ್ನು ನೋಡೋಣ. Android ಆವೃತ್ತಿಯಲ್ಲಿ ನಾವು ಯಾವುದೇ TL ಪಾರ್ಸರ್ ಅನ್ನು ಕಾಣುವುದಿಲ್ಲ, ಆದರೆ ನಾವು (ಡಿ) ಧಾರಾವಾಹಿಯೊಂದಿಗೆ ಭಾರಿ ಫೈಲ್ ಅನ್ನು (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;

ಈ ಕಾಮೆಂಟ್ "ಹಸ್ತಚಾಲಿತವಾಗಿ ರಚಿಸಲಾಗಿದೆ" ಈ ಫೈಲ್‌ನ ಭಾಗವನ್ನು ಮಾತ್ರ ಕೈಯಾರೆ ಬರೆಯಲಾಗಿದೆ ಎಂದು ಸೂಚಿಸುತ್ತದೆ (ಇಡೀ ನಿರ್ವಹಣೆ ದುಃಸ್ವಪ್ನವನ್ನು ನೀವು ಊಹಿಸಬಹುದೇ?), ಮತ್ತು ಉಳಿದವು ಯಂತ್ರ-ರಚಿತವಾಗಿದೆ. ಆದಾಗ್ಯೂ, ಇನ್ನೊಂದು ಪ್ರಶ್ನೆ ಉದ್ಭವಿಸುತ್ತದೆ - ಮೂಲಗಳು ಲಭ್ಯವಿದೆ ಸಂಪೂರ್ಣವಾಗಿ ಅಲ್ಲ (ಲಿನಕ್ಸ್ ಕರ್ನಲ್‌ನಲ್ಲಿ ಲಾ ಜಿಪಿಎಲ್ ಬ್ಲಾಬ್ಸ್), ಆದರೆ ಇದು ಈಗಾಗಲೇ ಎರಡನೇ ಭಾಗಕ್ಕೆ ವಿಷಯವಾಗಿದೆ.

ಆದರೆ ಸಾಕು. ಈ ಎಲ್ಲಾ ಧಾರಾವಾಹಿಗಳು ನಡೆಯುವ ಪ್ರೋಟೋಕಾಲ್‌ಗೆ ಹೋಗೋಣ.

ಎಂಟಿಪ್ರೊಟೊ

ಆದ್ದರಿಂದ, ತೆರೆಯೋಣ ಸಾಮಾನ್ಯ ವಿವರಣೆ и ಪ್ರೋಟೋಕಾಲ್ನ ವಿವರವಾದ ವಿವರಣೆ ಮತ್ತು ನಾವು ಎಡವಿ ಬೀಳುವ ಮೊದಲ ವಿಷಯವೆಂದರೆ ಪರಿಭಾಷೆ. ಮತ್ತು ಎಲ್ಲದರ ಸಮೃದ್ಧಿಯೊಂದಿಗೆ. ಸಾಮಾನ್ಯವಾಗಿ, ಇದು ಟೆಲಿಗ್ರಾಮ್‌ನ ಸ್ವಾಮ್ಯದ ವೈಶಿಷ್ಟ್ಯವೆಂದು ತೋರುತ್ತದೆ - ವಿಭಿನ್ನ ಸ್ಥಳಗಳಲ್ಲಿ ವಿಷಯಗಳನ್ನು ವಿಭಿನ್ನವಾಗಿ ಕರೆಯುವುದು, ಅಥವಾ ಒಂದು ಪದದಿಂದ ವಿಭಿನ್ನ ವಿಷಯಗಳನ್ನು ಅಥವಾ ಪ್ರತಿಯಾಗಿ (ಉದಾಹರಣೆಗೆ, ಉನ್ನತ ಮಟ್ಟದ API ನಲ್ಲಿ, ನೀವು ಸ್ಟಿಕ್ಕರ್ ಪ್ಯಾಕ್ ಅನ್ನು ನೋಡಿದರೆ, ಅದು ಅಲ್ಲ ನೀವು ಏನು ಯೋಚಿಸಿದ್ದೀರಿ).

ಉದಾಹರಣೆಗೆ, "ಸಂದೇಶ" ಮತ್ತು "ಸೆಷನ್" ಎಂದರೆ ಇಲ್ಲಿ ಸಾಮಾನ್ಯ ಟೆಲಿಗ್ರಾಮ್ ಕ್ಲೈಂಟ್ ಇಂಟರ್ಫೇಸ್‌ಗಿಂತ ವಿಭಿನ್ನವಾಗಿದೆ. ಒಳ್ಳೆಯದು, ಸಂದೇಶದೊಂದಿಗೆ ಎಲ್ಲವೂ ಸ್ಪಷ್ಟವಾಗಿದೆ, ಇದನ್ನು OOP ಪದಗಳಲ್ಲಿ ಅರ್ಥೈಸಬಹುದು ಅಥವಾ ಸರಳವಾಗಿ "ಪ್ಯಾಕೆಟ್" ಪದ ಎಂದು ಕರೆಯಬಹುದು - ಇದು ಕಡಿಮೆ, ಸಾರಿಗೆ ಮಟ್ಟವಾಗಿದೆ, ಇಂಟರ್ಫೇಸ್ನಲ್ಲಿರುವಂತೆ ಅದೇ ಸಂದೇಶಗಳಿಲ್ಲ, ಅನೇಕ ಸೇವಾ ಸಂದೇಶಗಳಿವೆ . ಆದರೆ ಅಧಿವೇಶನ ... ಆದರೆ ಮೊದಲ ವಿಷಯಗಳು ಮೊದಲು.

ಸಾರಿಗೆ ಪದರ

ಮೊದಲನೆಯದು ಸಾರಿಗೆ. ಅವರು 5 ಆಯ್ಕೆಗಳ ಬಗ್ಗೆ ನಮಗೆ ತಿಳಿಸುತ್ತಾರೆ:

  • TCP
  • ವೆಬ್‌ಸಾಕೆಟ್
  • HTTPS ಮೂಲಕ ವೆಬ್‌ಸಾಕೆಟ್
  • HTTP
  • , HTTPS

ವಾಸಿಲಿ, [15.06.18 15:04] UDP ಸಾರಿಗೆಯೂ ಇದೆ, ಆದರೆ ಅದನ್ನು ದಾಖಲಿಸಲಾಗಿಲ್ಲ

ಮತ್ತು ಮೂರು ರೂಪಾಂತರಗಳಲ್ಲಿ TCP

ಮೊದಲನೆಯದು TCP ಮೇಲೆ UDP ಅನ್ನು ಹೋಲುತ್ತದೆ, ಪ್ರತಿ ಪ್ಯಾಕೆಟ್ ಅನುಕ್ರಮ ಸಂಖ್ಯೆ ಮತ್ತು crc ಅನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ
ಕಾರ್ಟ್‌ನಲ್ಲಿ ದಾಖಲೆಗಳನ್ನು ಓದುವುದು ಏಕೆ ತುಂಬಾ ನೋವಿನಿಂದ ಕೂಡಿದೆ?

ಸರಿ, ಅದು ಈಗ ಇದೆ TCP ಈಗಾಗಲೇ 4 ರೂಪಾಂತರಗಳಲ್ಲಿದೆ:

  • ಸಂಕ್ಷಿಪ್ತ
  • ಮಧ್ಯಂತರ
  • ಪ್ಯಾಡ್ಡ್ ಮಧ್ಯಂತರ
  • ಪೂರ್ಣ

ಸರಿ, ಸರಿ, MTProxy ಗಾಗಿ ಪ್ಯಾಡ್ಡ್ ಇಂಟರ್ಮೀಡಿಯೇಟ್, ಇದನ್ನು ನಂತರ ಪ್ರಸಿದ್ಧ ಘಟನೆಗಳ ಕಾರಣದಿಂದಾಗಿ ಸೇರಿಸಲಾಯಿತು. ಆದರೆ ನೀವು ಒಂದನ್ನು ಪಡೆಯಬಹುದಾದಾಗ ಇನ್ನೂ ಎರಡು ಆವೃತ್ತಿಗಳು (ಒಟ್ಟು ಮೂರು) ಏಕೆ? ಎಲ್ಲಾ ನಾಲ್ಕು ಮೂಲಭೂತವಾಗಿ ಮುಖ್ಯ MTProto ನ ಉದ್ದ ಮತ್ತು ಪೇಲೋಡ್ ಅನ್ನು ಹೇಗೆ ಹೊಂದಿಸುವುದು ಎಂಬುದರಲ್ಲಿ ಮಾತ್ರ ಭಿನ್ನವಾಗಿರುತ್ತವೆ, ಅದನ್ನು ಮತ್ತಷ್ಟು ಚರ್ಚಿಸಲಾಗುವುದು:

  • ಸಂಕ್ಷೇಪಿತದಲ್ಲಿ ಇದು 1 ಅಥವಾ 4 ಬೈಟ್‌ಗಳು, ಆದರೆ 0xef ಅಲ್ಲ, ನಂತರ ದೇಹ
  • ಮಧ್ಯಂತರದಲ್ಲಿ ಇದು 4 ಬೈಟ್‌ಗಳ ಉದ್ದ ಮತ್ತು ಕ್ಷೇತ್ರವಾಗಿದೆ ಮತ್ತು ಮೊದಲ ಬಾರಿಗೆ ಕ್ಲೈಂಟ್ ಕಳುಹಿಸಬೇಕು 0xeeeeeeee ಇದು ಮಧ್ಯಂತರ ಎಂದು ಸೂಚಿಸಲು
  • ನೆಟ್‌ವರ್ಕರ್‌ನ ದೃಷ್ಟಿಕೋನದಿಂದ ಪೂರ್ಣವಾಗಿ ಹೆಚ್ಚು ವ್ಯಸನಕಾರಿ: ಉದ್ದ, ಅನುಕ್ರಮ ಸಂಖ್ಯೆ, ಮತ್ತು ಮುಖ್ಯವಾಗಿ MTProto, ದೇಹ, CRC32 ಅಲ್ಲ. ಹೌದು, ಇದೆಲ್ಲವೂ TCP ಯ ಮೇಲಿದೆ. ಇದು ನಮಗೆ ಅನುಕ್ರಮ ಬೈಟ್ ಸ್ಟ್ರೀಮ್ ರೂಪದಲ್ಲಿ ವಿಶ್ವಾಸಾರ್ಹ ಸಾರಿಗೆಯನ್ನು ಒದಗಿಸುತ್ತದೆ; ಯಾವುದೇ ಅನುಕ್ರಮಗಳ ಅಗತ್ಯವಿಲ್ಲ, ವಿಶೇಷವಾಗಿ ಚೆಕ್‌ಸಮ್‌ಗಳು. ಸರಿ, ಈಗ ಯಾರಾದರೂ TCP 16-ಬಿಟ್ ಚೆಕ್ಸಮ್ ಅನ್ನು ಹೊಂದಿದೆ ಎಂದು ನನಗೆ ಆಕ್ಷೇಪಿಸುತ್ತಾರೆ, ಆದ್ದರಿಂದ ಡೇಟಾ ಭ್ರಷ್ಟಾಚಾರ ಸಂಭವಿಸುತ್ತದೆ. ಅದ್ಭುತವಾಗಿದೆ, ಆದರೆ ನಾವು ವಾಸ್ತವವಾಗಿ 16 ಬೈಟ್‌ಗಳಿಗಿಂತ ಉದ್ದವಾದ ಹ್ಯಾಶ್‌ಗಳೊಂದಿಗೆ ಕ್ರಿಪ್ಟೋಗ್ರಾಫಿಕ್ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಹೊಂದಿದ್ದೇವೆ, ಈ ಎಲ್ಲಾ ದೋಷಗಳು - ಮತ್ತು ಇನ್ನೂ ಹೆಚ್ಚಿನವು - ಉನ್ನತ ಮಟ್ಟದಲ್ಲಿ SHA ಅಸಾಮರಸ್ಯದಿಂದ ಹಿಡಿಯಲಾಗುತ್ತದೆ. ಇದರ ಮೇಲೆ CRC32 ನಲ್ಲಿ ಯಾವುದೇ ಪಾಯಿಂಟ್ ಇಲ್ಲ.

ಸಂಕ್ಷೇಪಿತವನ್ನು ಹೋಲಿಸೋಣ, ಇದರಲ್ಲಿ ಒಂದು ಬೈಟ್ ಉದ್ದ ಸಾಧ್ಯ, ಮಧ್ಯಂತರದೊಂದಿಗೆ, ಇದು "4-ಬೈಟ್ ಡೇಟಾ ಜೋಡಣೆ ಅಗತ್ಯವಿದ್ದರೆ" ಸಮರ್ಥಿಸುತ್ತದೆ, ಇದು ಸಾಕಷ್ಟು ಅಸಂಬದ್ಧವಾಗಿದೆ. ಏನು, ಟೆಲಿಗ್ರಾಮ್ ಪ್ರೋಗ್ರಾಮರ್‌ಗಳು ಎಷ್ಟು ಅಸಮರ್ಥರಾಗಿದ್ದಾರೆ ಎಂದು ನಂಬಲಾಗಿದೆ, ಅವರು ಸಾಕೆಟ್‌ನಿಂದ ಡೇಟಾವನ್ನು ಜೋಡಿಸಿದ ಬಫರ್‌ಗೆ ಓದಲಾಗುವುದಿಲ್ಲ? ನೀವು ಇನ್ನೂ ಇದನ್ನು ಮಾಡಬೇಕಾಗಿದೆ, ಏಕೆಂದರೆ ಓದುವಿಕೆಯು ನಿಮಗೆ ಯಾವುದೇ ಸಂಖ್ಯೆಯ ಬೈಟ್‌ಗಳನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ (ಮತ್ತು ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌ಗಳು ಸಹ ಇವೆ, ಉದಾಹರಣೆಗೆ...). ಅಥವಾ ಮತ್ತೊಂದೆಡೆ, ನಾವು ಇನ್ನೂ 16 ಬೈಟ್‌ಗಳ ಮೇಲೆ ಭಾರಿ ಪ್ಯಾಡಿಂಗ್ ಹೊಂದಿದ್ದರೆ ಸಂಕ್ಷೇಪಿಸುವಿಕೆಯನ್ನು ಏಕೆ ನಿರ್ಬಂಧಿಸಬೇಕು - 3 ಬೈಟ್‌ಗಳನ್ನು ಉಳಿಸಿ ಕೆಲವೊಮ್ಮೆ ?

ನಿಕೊಲಾಯ್ ಡುರೊವ್ ನಿಜವಾಗಿಯೂ ಯಾವುದೇ ನೈಜ ಪ್ರಾಯೋಗಿಕ ಅಗತ್ಯವಿಲ್ಲದೆಯೇ ನೆಟ್‌ವರ್ಕ್ ಪ್ರೋಟೋಕಾಲ್‌ಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ಚಕ್ರಗಳನ್ನು ಮರುಶೋಧಿಸಲು ಇಷ್ಟಪಡುತ್ತಾರೆ ಎಂಬ ಅಭಿಪ್ರಾಯವನ್ನು ಒಬ್ಬರು ಪಡೆಯುತ್ತಾರೆ.

ಇತರ ಸಾರಿಗೆ ಆಯ್ಕೆಗಳು, incl. ವೆಬ್ ಮತ್ತು MTProxy, ನಾವು ಈಗ ಪರಿಗಣಿಸುವುದಿಲ್ಲ, ಬಹುಶಃ ಇನ್ನೊಂದು ಪೋಸ್ಟ್‌ನಲ್ಲಿ, ವಿನಂತಿಯಿದ್ದರೆ. ಇದೇ MTProxy ಬಗ್ಗೆ, 2018 ರಲ್ಲಿ ಬಿಡುಗಡೆಯಾದ ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ, ಪೂರೈಕೆದಾರರು ಅದನ್ನು ನಿರ್ಬಂಧಿಸಲು ತ್ವರಿತವಾಗಿ ಕಲಿತರು, ಬೈಪಾಸ್ ತಡೆಗಟ್ಟುವಿಕೆಪ್ರಕಾರ ಪ್ಯಾಕೇಜ್ ಗಾತ್ರ! ಮತ್ತು ಸಿ ಯಲ್ಲಿ ಬರೆದಿರುವ (ಮತ್ತೆ ವಾಲ್ಟ್‌ಮ್ಯಾನ್‌ನಿಂದ) MTProxy ಸರ್ವರ್ ಅನ್ನು ಲಿನಕ್ಸ್ ವಿಶೇಷತೆಗಳಿಗೆ ಅತಿಯಾಗಿ ಜೋಡಿಸಲಾಗಿದೆ, ಆದಾಗ್ಯೂ ಇದು ಅಗತ್ಯವಿಲ್ಲದಿದ್ದರೂ (ಫಿಲ್ ಕುಲಿನ್ ಖಚಿತಪಡಿಸುತ್ತದೆ), ಮತ್ತು Go ಅಥವಾ Node.js ನಲ್ಲಿ ಇದೇ ರೀತಿಯ ಸರ್ವರ್ ಇರುತ್ತದೆ ನೂರಕ್ಕಿಂತ ಕಡಿಮೆ ಸಾಲುಗಳಲ್ಲಿ ಹೊಂದಿಕೊಳ್ಳುತ್ತದೆ.

ಆದರೆ ಇತರ ಸಮಸ್ಯೆಗಳನ್ನು ಪರಿಗಣಿಸಿದ ನಂತರ ವಿಭಾಗದ ಕೊನೆಯಲ್ಲಿ ಈ ಜನರ ತಾಂತ್ರಿಕ ಸಾಕ್ಷರತೆಯ ಬಗ್ಗೆ ನಾವು ತೀರ್ಮಾನಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತೇವೆ. ಸದ್ಯಕ್ಕೆ, ನಾವು OSI ಲೇಯರ್ 5, ಸೆಷನ್‌ಗೆ ಹೋಗೋಣ - ಅದರ ಮೇಲೆ ಅವರು MTProto ಸೆಶನ್ ಅನ್ನು ಇರಿಸಿದರು.

ಕೀಗಳು, ಸಂದೇಶಗಳು, ಅವಧಿಗಳು, ಡಿಫಿ-ಹೆಲ್ಮನ್

ಅವರು ಅದನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಸರಿಯಾಗಿ ಇರಿಸಿಲ್ಲ... ಸಕ್ರಿಯ ಸೆಷನ್‌ಗಳ ಅಡಿಯಲ್ಲಿ ಇಂಟರ್‌ಫೇಸ್‌ನಲ್ಲಿ ಗೋಚರಿಸುವ ಸೆಷನ್ ಒಂದೇ ಸೆಷನ್ ಅಲ್ಲ. ಆದರೆ ಕ್ರಮದಲ್ಲಿ.

ಟೆಲಿಗ್ರಾಮ್‌ನ ಪ್ರೋಟೋಕಾಲ್ ಮತ್ತು ಸಾಂಸ್ಥಿಕ ವಿಧಾನಗಳ ಟೀಕೆ. ಭಾಗ 1, ತಾಂತ್ರಿಕ: ಮೊದಲಿನಿಂದ ಕ್ಲೈಂಟ್ ಬರೆಯುವ ಅನುಭವ - TL, MT

ಆದ್ದರಿಂದ ನಾವು ಸಾರಿಗೆ ಪದರದಿಂದ ತಿಳಿದಿರುವ ಉದ್ದದ ಬೈಟ್ ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಸ್ವೀಕರಿಸಿದ್ದೇವೆ. ಇದು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಿದ ಸಂದೇಶ ಅಥವಾ ಸರಳ ಪಠ್ಯ - ನಾವು ಇನ್ನೂ ಪ್ರಮುಖ ಒಪ್ಪಂದದ ಹಂತದಲ್ಲಿದ್ದರೆ ಮತ್ತು ಅದನ್ನು ನಿಜವಾಗಿ ಮಾಡುತ್ತಿದ್ದರೆ. ನಾವು "ಕೀ" ಎಂಬ ಪರಿಕಲ್ಪನೆಗಳ ಗುಂಪನ್ನು ಕುರಿತು ಮಾತನಾಡುತ್ತಿದ್ದೇವೆ? ಈ ಸಮಸ್ಯೆಯನ್ನು ಟೆಲಿಗ್ರಾಮ್ ತಂಡಕ್ಕಾಗಿಯೇ ಸ್ಪಷ್ಟಪಡಿಸೋಣ (ಬೆಳಿಗ್ಗೆ 4 ಗಂಟೆಗೆ ದಣಿದ ಮೆದುಳಿನೊಂದಿಗೆ ಇಂಗ್ಲಿಷ್‌ನಿಂದ ನನ್ನ ಸ್ವಂತ ದಾಖಲಾತಿಯನ್ನು ಭಾಷಾಂತರಿಸಿದ್ದಕ್ಕಾಗಿ ನಾನು ಕ್ಷಮೆಯಾಚಿಸುತ್ತೇನೆ, ಕೆಲವು ನುಡಿಗಟ್ಟುಗಳನ್ನು ಹಾಗೆಯೇ ಬಿಡುವುದು ಸುಲಭವಾಗಿದೆ):

ಎಂಬ ಎರಡು ಘಟಕಗಳಿವೆ ಅಧಿವೇಶನ - "ಪ್ರಸ್ತುತ ಸೆಷನ್‌ಗಳು" ಅಡಿಯಲ್ಲಿ ಅಧಿಕೃತ ಕ್ಲೈಂಟ್‌ಗಳ UI ನಲ್ಲಿ ಒಂದು, ಪ್ರತಿ ಸೆಷನ್ ಸಂಪೂರ್ಣ ಸಾಧನ / OS ಗೆ ಅನುರೂಪವಾಗಿದೆ.
ಎರಡನೆಯದು MTProto ಅಧಿವೇಶನ, ಅದರಲ್ಲಿ ಸಂದೇಶದ ಅನುಕ್ರಮ ಸಂಖ್ಯೆಯನ್ನು (ಕಡಿಮೆ ಮಟ್ಟದ ಅರ್ಥದಲ್ಲಿ) ಹೊಂದಿದೆ ಮತ್ತು ಯಾವುದು ವಿಭಿನ್ನ TCP ಸಂಪರ್ಕಗಳ ನಡುವೆ ಉಳಿಯಬಹುದು. ಒಂದೇ ಸಮಯದಲ್ಲಿ ಹಲವಾರು MTProto ಸೆಷನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಬಹುದು, ಉದಾಹರಣೆಗೆ, ಫೈಲ್ ಡೌನ್‌ಲೋಡ್ ಅನ್ನು ವೇಗಗೊಳಿಸಲು.

ಈ ಎರಡರ ನಡುವೆ ಅವಧಿಗಳು ಒಂದು ಪರಿಕಲ್ಪನೆ ಇದೆ ದೃ ization ೀಕರಣ. ಕ್ಷೀಣಿಸಿದ ಸಂದರ್ಭದಲ್ಲಿ, ನಾವು ಅದನ್ನು ಹೇಳಬಹುದು UI ಸೆಷನ್ ಅದೇ ಆಗಿದೆ ದೃ ization ೀಕರಣ, ಆದರೆ ಅಯ್ಯೋ, ಎಲ್ಲವೂ ಸಂಕೀರ್ಣವಾಗಿದೆ. ಬನ್ನಿ ನೋಡೋಣ:

  • ಹೊಸ ಸಾಧನದಲ್ಲಿ ಬಳಕೆದಾರರು ಮೊದಲು ಉತ್ಪಾದಿಸುತ್ತಾರೆ auth_key ಮತ್ತು ಅದನ್ನು ಖಾತೆಗೆ ಬಂಧಿಸುತ್ತದೆ, ಉದಾಹರಣೆಗೆ SMS ಮೂಲಕ - ಅದಕ್ಕಾಗಿಯೇ ದೃ ization ೀಕರಣ
  • ಇದು ಮೊದಲ ಒಳಗೆ ಸಂಭವಿಸಿತು MTProto ಅಧಿವೇಶನ, ಇದು ಹೊಂದಿದೆ session_id ನಿಮ್ಮೊಳಗೆ.
  • ಈ ಹಂತದಲ್ಲಿ, ಸಂಯೋಜನೆ ದೃ ization ೀಕರಣ и session_id ಕರೆಯಬಹುದು ಉದಾಹರಣೆಗೆ - ಈ ಪದವು ಕೆಲವು ಕ್ಲೈಂಟ್‌ಗಳ ದಸ್ತಾವೇಜನ್ನು ಮತ್ತು ಕೋಡ್‌ನಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ
  • ನಂತರ, ಕ್ಲೈಂಟ್ ತೆರೆಯಬಹುದು ಹಲವಾರು MTProto ಅವಧಿಗಳು ಅದೇ ಅಡಿಯಲ್ಲಿ auth_key - ಅದೇ ಡಿಸಿಗೆ.
  • ನಂತರ, ಒಂದು ದಿನ ಕ್ಲೈಂಟ್ ಫೈಲ್ ಅನ್ನು ವಿನಂತಿಸಬೇಕಾಗುತ್ತದೆ ಇನ್ನೊಬ್ಬ ಡಿಸಿ - ಮತ್ತು ಈ DC ಗಾಗಿ ಹೊಸದನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ auth_key !
  • ನೋಂದಾಯಿಸುತ್ತಿರುವ ಹೊಸ ಬಳಕೆದಾರರಲ್ಲ, ಆದರೆ ಅದೇ ಎಂದು ಸಿಸ್ಟಮ್ಗೆ ತಿಳಿಸಲು ದೃ ization ೀಕರಣ (UI ಸೆಷನ್), ಕ್ಲೈಂಟ್ API ಕರೆಗಳನ್ನು ಬಳಸುತ್ತದೆ auth.exportAuthorization ಮನೆಯಲ್ಲಿ ಡಿಸಿ auth.importAuthorization ಹೊಸ DC ಯಲ್ಲಿ.
  • ಎಲ್ಲವೂ ಒಂದೇ ಆಗಿರುತ್ತದೆ, ಹಲವಾರು ತೆರೆದಿರಬಹುದು MTProto ಅವಧಿಗಳು (ಪ್ರತಿಯೊಂದೂ ತನ್ನದೇ ಆದ session_id) ಈ ಹೊಸ DC ಗೆ, ಅಡಿಯಲ್ಲಿ ತನ್ನ auth_key.
  • ಅಂತಿಮವಾಗಿ, ಕ್ಲೈಂಟ್ ಪರಿಪೂರ್ಣ ಫಾರ್ವರ್ಡ್ ಗೌಪ್ಯತೆಯನ್ನು ಬಯಸಬಹುದು. ಪ್ರತಿ auth_key ಆಗಿತ್ತು ಶಾಶ್ವತ ಕೀ - ಪ್ರತಿ DC - ಮತ್ತು ಕ್ಲೈಂಟ್ ಕರೆ ಮಾಡಬಹುದು auth.bindTempAuthKey ಬಳಕೆಗೆ ತಾತ್ಕಾಲಿಕ auth_key - ಮತ್ತು ಮತ್ತೆ, ಕೇವಲ ಒಂದು temp_auth_key ಪ್ರತಿ DC, ಎಲ್ಲರಿಗೂ ಸಾಮಾನ್ಯ MTProto ಅವಧಿಗಳು ಈ ಡಿಸಿಗೆ.

ಅದನ್ನು ಗಮನಿಸಿ ಉಪ್ಪು (ಮತ್ತು ಭವಿಷ್ಯದ ಲವಣಗಳು) ಸಹ ಒಂದು auth_key ಆ. ಎಲ್ಲರ ನಡುವೆ ಹಂಚಿಕೊಂಡಿದ್ದಾರೆ MTProto ಅವಧಿಗಳು ಅದೇ ಡಿಸಿಗೆ.

"ವಿವಿಧ TCP ಸಂಪರ್ಕಗಳ ನಡುವೆ" ಎಂದರೆ ಏನು? ಆದ್ದರಿಂದ ಇದರ ಅರ್ಥ ಏನೋ ಹಾಗೆ ವೆಬ್‌ಸೈಟ್‌ನಲ್ಲಿ ಅಧಿಕೃತ ಕುಕೀ - ಇದು ನೀಡಿದ ಸರ್ವರ್‌ಗೆ ಅನೇಕ TCP ಸಂಪರ್ಕಗಳನ್ನು ಮುಂದುವರೆಸುತ್ತದೆ (ಬದುಕುಳಿಯುತ್ತದೆ), ಆದರೆ ಒಂದು ದಿನ ಅದು ಕೆಟ್ಟದಾಗುತ್ತದೆ. HTTP ಗಿಂತ ಭಿನ್ನವಾಗಿ, ಒಂದು ಸೆಷನ್‌ನೊಳಗಿನ MTProto ಸಂದೇಶಗಳನ್ನು ಅನುಕ್ರಮವಾಗಿ ಸಂಖ್ಯೆ ಮತ್ತು ದೃಢೀಕರಿಸಲಾಗುತ್ತದೆ; ಅವರು ಸುರಂಗವನ್ನು ಪ್ರವೇಶಿಸಿದರೆ, ಸಂಪರ್ಕವು ಮುರಿದುಹೋಗಿದೆ - ಹೊಸ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಿದ ನಂತರ, ಸರ್ವರ್ ಈ ಸೆಷನ್‌ನಲ್ಲಿ ಹಿಂದಿನ ಅವಧಿಯಲ್ಲಿ ವಿತರಿಸದ ಎಲ್ಲವನ್ನೂ ದಯೆಯಿಂದ ಕಳುಹಿಸುತ್ತದೆ. TCP ಸಂಪರ್ಕ.

ಆದಾಗ್ಯೂ, ಮೇಲಿನ ಮಾಹಿತಿಯನ್ನು ಹಲವು ತಿಂಗಳ ತನಿಖೆಯ ನಂತರ ಸಂಕ್ಷಿಪ್ತಗೊಳಿಸಲಾಗಿದೆ. ಈ ಮಧ್ಯೆ, ನಾವು ನಮ್ಮ ಕ್ಲೈಂಟ್ ಅನ್ನು ಮೊದಲಿನಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತಿದ್ದೇವೆಯೇ? - ಆರಂಭಕ್ಕೆ ಹಿಂತಿರುಗಿ ನೋಡೋಣ.

ಆದ್ದರಿಂದ ನಾವು ಉತ್ಪಾದಿಸೋಣ auth_key ಮೇಲೆ ಟೆಲಿಗ್ರಾಮ್‌ನಿಂದ ಡಿಫಿ-ಹೆಲ್‌ಮ್ಯಾನ್ ಆವೃತ್ತಿಗಳು. ದಸ್ತಾವೇಜನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಪ್ರಯತ್ನಿಸೋಣ...

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. ಆದರೆ ಈ ತೋರಿಕೆಯಲ್ಲಿ ಸರಳ ಕಾರ್ಯಾಚರಣೆಯು ಯಶಸ್ವಿಯಾಗುತ್ತದೆ, ನೀವು ಏನು ಎದುರಿಸಬೇಕಾಗುತ್ತದೆ?

ವಾಸಿಲಿ, [20.06.18/00/26 XNUMX:XNUMX] ನಾನು ಇನ್ನೂ appid ವಿನಂತಿಯನ್ನು ಪಡೆದಿಲ್ಲ

ನಾನು ಈ ವಿನಂತಿಯನ್ನು DH ಗೆ ಕಳುಹಿಸಿದ್ದೇನೆ

ಮತ್ತು, ಸಾರಿಗೆ ಡಾಕ್‌ನಲ್ಲಿ ಅದು ದೋಷ ಕೋಡ್‌ನ 4 ಬೈಟ್‌ಗಳೊಂದಿಗೆ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು ಎಂದು ಹೇಳುತ್ತದೆ. ಅಷ್ಟೇ

ಸರಿ, ಅವರು ನನಗೆ ಹೇಳಿದರು -404, ಹಾಗಾದರೆ ಏನು?

ಹಾಗಾಗಿ ನಾನು ಅವನಿಗೆ ಹೇಳಿದೆ: “ಈ ರೀತಿಯ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ನೊಂದಿಗೆ ಸರ್ವರ್ ಕೀಲಿಯೊಂದಿಗೆ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾದ ನಿಮ್ಮ ಬುಲ್‌ಶಿಟ್ ಅನ್ನು ಹಿಡಿಯಿರಿ, ನನಗೆ DH ಬೇಕು,” ಮತ್ತು ಅದು ಮೂರ್ಖ 404 ನೊಂದಿಗೆ ಪ್ರತಿಕ್ರಿಯಿಸಿತು

ಈ ಸರ್ವರ್ ಪ್ರತಿಕ್ರಿಯೆಯ ಬಗ್ಗೆ ನೀವು ಏನು ಯೋಚಿಸುತ್ತೀರಿ? ಏನ್ ಮಾಡೋದು? ಕೇಳಲು ಯಾರೂ ಇಲ್ಲ (ಆದರೆ ಎರಡನೇ ಭಾಗದಲ್ಲಿ ಅದರ ಬಗ್ಗೆ ಹೆಚ್ಚು).

ಇಲ್ಲಿ ಎಲ್ಲಾ ಆಸಕ್ತಿಯನ್ನು ಡಾಕ್‌ನಲ್ಲಿ ಮಾಡಲಾಗುತ್ತದೆ

ನನಗೆ ಬೇರೆ ಕೆಲಸವಿಲ್ಲ, ನಾನು ಸಂಖ್ಯೆಗಳನ್ನು ಹಿಂದಕ್ಕೆ ಮತ್ತು ಮುಂದಕ್ಕೆ ಪರಿವರ್ತಿಸುವ ಕನಸು ಕಂಡೆ

ಎರಡು 32 ಬಿಟ್ ಸಂಖ್ಯೆಗಳು. ನಾನು ಎಲ್ಲರಂತೆ ಅವುಗಳನ್ನು ಪ್ಯಾಕ್ ಮಾಡಿದೆ

ಆದರೆ ಇಲ್ಲ, ಈ ಎರಡನ್ನು ಮೊದಲು ಸಾಲಿಗೆ ಬಿಇ ಎಂದು ಸೇರಿಸಬೇಕಾಗಿದೆ

ವಾಡಿಮ್ ಗೊಂಚರೋವ್, [20.06.18 15:49] ಮತ್ತು ಈ 404 ಕಾರಣದಿಂದಾಗಿ?

ವಾಸಿಲಿ, [20.06.18 15:49] ಹೌದು!

ವಾಡಿಮ್ ಗೊಂಚರೋವ್, [20.06.18 15:50] ಹಾಗಾಗಿ ಅವನು "ಕಂಡುಹಿಡಿಯಲಿಲ್ಲ" ಎಂಬುದನ್ನು ನನಗೆ ಅರ್ಥವಾಗುತ್ತಿಲ್ಲ

ವಾಸಿಲಿ, [20.06.18 15:50] ಸರಿಸುಮಾರು

ಅಂತಹ ವಿಭಜನೆಯನ್ನು ಅವಿಭಾಜ್ಯ ಅಂಶಗಳಾಗಿ ನಾನು ಕಂಡುಹಿಡಿಯಲಾಗಲಿಲ್ಲ%)

ನಾವು ದೋಷ ವರದಿ ಮಾಡುವಿಕೆಯನ್ನು ಸಹ ನಿರ್ವಹಿಸಲಿಲ್ಲ

ವಾಸಿಲಿ, [20.06.18 20:18] ಓಹ್, MD5 ಕೂಡ ಇದೆ. ಈಗಾಗಲೇ ಮೂರು ವಿಭಿನ್ನ ಹ್ಯಾಶ್‌ಗಳು

ಪ್ರಮುಖ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಈ ಕೆಳಗಿನಂತೆ ಲೆಕ್ಕಹಾಕಲಾಗುತ್ತದೆ:

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

SHA1 ಮತ್ತು sha2

ಆದ್ದರಿಂದ ಅದನ್ನು ಹಾಕೋಣ auth_key ಡಿಫಿ-ಹೆಲ್‌ಮ್ಯಾನ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ನಾವು 2048 ಬಿಟ್‌ಗಳನ್ನು ಗಾತ್ರದಲ್ಲಿ ಸ್ವೀಕರಿಸಿದ್ದೇವೆ. ಮುಂದೇನು? ಮುಂದೆ ಈ ಕೀಲಿಯ ಕಡಿಮೆ 1024 ಬಿಟ್‌ಗಳನ್ನು ಯಾವುದೇ ರೀತಿಯಲ್ಲಿ ಬಳಸಲಾಗುವುದಿಲ್ಲ ಎಂದು ನಾವು ಕಂಡುಕೊಳ್ಳುತ್ತೇವೆ ... ಆದರೆ ಇದೀಗ ಇದರ ಬಗ್ಗೆ ಯೋಚಿಸೋಣ. ಈ ಹಂತದಲ್ಲಿ, ನಾವು ಸರ್ವರ್‌ನೊಂದಿಗೆ ಹಂಚಿಕೊಂಡ ರಹಸ್ಯವನ್ನು ಹೊಂದಿದ್ದೇವೆ. TLS ಅಧಿವೇಶನದ ಅನಲಾಗ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿದೆ, ಇದು ತುಂಬಾ ದುಬಾರಿ ವಿಧಾನವಾಗಿದೆ. ಆದರೆ ಸರ್ವರಿಗೂ ನಾವು ಯಾರೆಂದು ಇನ್ನೂ ತಿಳಿದಿಲ್ಲ! ಇನ್ನೂ ಇಲ್ಲ, ವಾಸ್ತವವಾಗಿ. ಅಧಿಕಾರ. ಆ. ನೀವು ಒಮ್ಮೆ ICQ ನಲ್ಲಿ ಮಾಡಿದಂತೆ "ಲಾಗಿನ್-ಪಾಸ್‌ವರ್ಡ್" ವಿಷಯದಲ್ಲಿ ಯೋಚಿಸಿದ್ದರೆ, ಅಥವಾ SSH ನಲ್ಲಿರುವಂತೆ ಕನಿಷ್ಠ "ಲಾಗಿನ್-ಕೀ" (ಉದಾಹರಣೆಗೆ, ಕೆಲವು gitlab/github ನಲ್ಲಿ). ನಾವು ಅನಾಮಧೇಯರನ್ನು ಸ್ವೀಕರಿಸಿದ್ದೇವೆ. ಸರ್ವರ್ ನಮಗೆ "ಈ ಫೋನ್ ಸಂಖ್ಯೆಗಳನ್ನು ಮತ್ತೊಂದು DC ಮೂಲಕ ಸೇವೆ ಸಲ್ಲಿಸಲಾಗಿದೆ" ಎಂದು ಹೇಳಿದರೆ ಏನು? ಅಥವಾ "ನಿಮ್ಮ ಫೋನ್ ಸಂಖ್ಯೆಯನ್ನು ನಿಷೇಧಿಸಲಾಗಿದೆ"? ನಾವು ಮಾಡಬಹುದಾದ ಅತ್ಯುತ್ತಮವಾದುದೆಂದರೆ, ಕೀಲಿಯು ಉಪಯುಕ್ತವಾಗಿದೆ ಮತ್ತು ಆ ಹೊತ್ತಿಗೆ ಕೊಳೆತು ಹೋಗುವುದಿಲ್ಲ ಎಂಬ ಭರವಸೆಯಲ್ಲಿ ಇಟ್ಟುಕೊಳ್ಳುವುದು.

ಮೂಲಕ, ನಾವು ಅದನ್ನು ಮೀಸಲಾತಿಯೊಂದಿಗೆ "ಸ್ವೀಕರಿಸಿದ್ದೇವೆ". ಉದಾಹರಣೆಗೆ, ನಾವು ಸರ್ವರ್ ಅನ್ನು ನಂಬುತ್ತೇವೆಯೇ? ಅದು ನಕಲಿಯಾಗಿದ್ದರೆ ಏನು? ಕ್ರಿಪ್ಟೋಗ್ರಾಫಿಕ್ ಪರಿಶೀಲನೆಗಳು ಅಗತ್ಯವಿದೆ:

ವಾಸಿಲಿ, [21.06.18 17:53] ಅವರು ಮೊಬೈಲ್ ಕ್ಲೈಂಟ್‌ಗಳಿಗೆ 2kbit ಸಂಖ್ಯೆಯನ್ನು ಪ್ರೈಮಾಲಿಟಿ% ಗಾಗಿ ಪರಿಶೀಲಿಸಲು ನೀಡುತ್ತಾರೆ)

ಆದರೆ ಇದು ಸ್ಪಷ್ಟವಾಗಿಲ್ಲ, ನಫೀಜೋವಾ

Vasily, [21.06.18 18:02] ಡಾಕ್ಯುಮೆಂಟ್ ಸರಳವಾಗಿಲ್ಲ ಎಂದು ತಿರುಗಿದರೆ ಏನು ಮಾಡಬೇಕೆಂದು ಹೇಳುವುದಿಲ್ಲ

ಹೇಳಿಲ್ಲ. ಈ ಸಂದರ್ಭದಲ್ಲಿ ಅಧಿಕೃತ ಆಂಡ್ರಾಯ್ಡ್ ಕ್ಲೈಂಟ್ ಏನು ಮಾಡುತ್ತದೆ ಎಂದು ನೋಡೋಣ? ಎ ಅದು ಏನು (ಮತ್ತು ಹೌದು, ಇಡೀ ಫೈಲ್ ಆಸಕ್ತಿದಾಯಕವಾಗಿದೆ) - ಅವರು ಹೇಳಿದಂತೆ, ನಾನು ಇದನ್ನು ಇಲ್ಲಿ ಬಿಡುತ್ತೇನೆ:

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

ಇಲ್ಲ, ಖಂಡಿತ ಅದು ಇನ್ನೂ ಇದೆ ಕೆಲವು ಸಂಖ್ಯೆಯ ಪ್ರಾಮುಖ್ಯತೆಗಾಗಿ ಪರೀಕ್ಷೆಗಳಿವೆ, ಆದರೆ ವೈಯಕ್ತಿಕವಾಗಿ ನನಗೆ ಗಣಿತದ ಸಾಕಷ್ಟು ಜ್ಞಾನವಿಲ್ಲ.

ಸರಿ, ನಾವು ಮಾಸ್ಟರ್ ಕೀಯನ್ನು ಪಡೆದುಕೊಂಡಿದ್ದೇವೆ. ಲಾಗ್ ಇನ್ ಮಾಡಲು, ಅಂದರೆ. ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸಿ, ನೀವು AES ಬಳಸಿಕೊಂಡು ಮತ್ತಷ್ಟು ಗೂಢಲಿಪೀಕರಣವನ್ನು ನಿರ್ವಹಿಸಬೇಕಾಗುತ್ತದೆ.

ದೃಢೀಕರಣ ಕೀಲಿಯಿಂದ ತೆಗೆದ 128 ಬೈಟ್‌ಗಳಿಂದ ಪೂರ್ವಭಾವಿಯಾಗಿ ಪ್ಯಾಡಿಂಗ್ ಬೈಟ್‌ಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ಸಂದೇಶದ ಪ್ರಮುಖ (ಸೆಶನ್, ಸಂದೇಶ ID, ಇತ್ಯಾದಿ ಸೇರಿದಂತೆ) SHA256 ನ 32 ಮಧ್ಯದ ಬಿಟ್‌ಗಳಾಗಿ ಸಂದೇಶದ ಕೀಯನ್ನು ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ.

ವಾಸಿಲಿ, [22.06.18 14:08] ಸರಾಸರಿ, ಬಿಚ್, ಬಿಟ್ಸ್

ಅರ್ಥವಾಯಿತು auth_key. ಎಲ್ಲಾ. ಅವುಗಳನ್ನು ಮೀರಿ ... ಇದು ಡಾಕ್ಯುಮೆಂಟ್ನಿಂದ ಸ್ಪಷ್ಟವಾಗಿಲ್ಲ. ಮುಕ್ತ ಮೂಲ ಕೋಡ್ ಅನ್ನು ಅಧ್ಯಯನ ಮಾಡಲು ಹಿಂಜರಿಯಬೇಡಿ.

MTProto 2.0 ಗೆ 12 ರಿಂದ 1024 ಬೈಟ್‌ಗಳ ಪ್ಯಾಡಿಂಗ್ ಅಗತ್ಯವಿದೆ ಎಂಬುದನ್ನು ಗಮನಿಸಿ, ಫಲಿತಾಂಶದ ಸಂದೇಶದ ಉದ್ದವು 16 ಬೈಟ್‌ಗಳಿಂದ ಭಾಗಿಸಬಹುದಾದ ಷರತ್ತಿಗೆ ಒಳಪಟ್ಟಿರುತ್ತದೆ.

ಹಾಗಾದರೆ ನೀವು ಎಷ್ಟು ಪ್ಯಾಡಿಂಗ್ ಅನ್ನು ಸೇರಿಸಬೇಕು?

ಮತ್ತು ಹೌದು, ದೋಷದ ಸಂದರ್ಭದಲ್ಲಿ 404 ಸಹ ಇದೆ

ಡಾಕ್ಯುಮೆಂಟೇಶನ್‌ನ ರೇಖಾಚಿತ್ರ ಮತ್ತು ಪಠ್ಯವನ್ನು ಯಾರಾದರೂ ಎಚ್ಚರಿಕೆಯಿಂದ ಅಧ್ಯಯನ ಮಾಡಿದರೆ, ಅಲ್ಲಿ ಯಾವುದೇ MAC ಇಲ್ಲ ಎಂದು ಅವರು ಗಮನಿಸಿದರು. ಮತ್ತು AES ಅನ್ನು ನಿರ್ದಿಷ್ಟ IGE ಮೋಡ್‌ನಲ್ಲಿ ಬಳಸಲಾಗುತ್ತದೆ, ಅದನ್ನು ಬೇರೆಲ್ಲಿಯೂ ಬಳಸಲಾಗುವುದಿಲ್ಲ. ಅವರು ಸಹಜವಾಗಿ, ತಮ್ಮ FAQ ನಲ್ಲಿ ಇದರ ಬಗ್ಗೆ ಬರೆಯುತ್ತಾರೆ... ಇಲ್ಲಿ, ಸಂದೇಶದ ಕೀಲಿಯು ಸ್ವತಃ ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡಲಾದ ಡೇಟಾದ SHA ಹ್ಯಾಶ್ ಆಗಿದೆ, ಸಮಗ್ರತೆಯನ್ನು ಪರಿಶೀಲಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ - ಮತ್ತು ಹೊಂದಾಣಿಕೆಯಾಗದಿದ್ದಲ್ಲಿ, ಕೆಲವು ಕಾರಣಗಳಿಗಾಗಿ ದಾಖಲಾತಿ ಮೌನವಾಗಿ ಅವರನ್ನು ನಿರ್ಲಕ್ಷಿಸಲು ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ (ಆದರೆ ಭದ್ರತೆಯ ಬಗ್ಗೆ ಏನು, ಅವರು ನಮ್ಮನ್ನು ಮುರಿದರೆ ಏನು?).

ನಾನು ಕ್ರಿಪ್ಟೋಗ್ರಾಫರ್ ಅಲ್ಲ, ಬಹುಶಃ ಸೈದ್ಧಾಂತಿಕ ದೃಷ್ಟಿಕೋನದಿಂದ ಈ ಸಂದರ್ಭದಲ್ಲಿ ಈ ಮೋಡ್‌ನಲ್ಲಿ ಯಾವುದೇ ತಪ್ಪಿಲ್ಲ. ಆದರೆ ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್ ಅನ್ನು ಉದಾಹರಣೆಯಾಗಿ ಬಳಸಿಕೊಂಡು ಪ್ರಾಯೋಗಿಕ ಸಮಸ್ಯೆಯನ್ನು ನಾನು ಸ್ಪಷ್ಟವಾಗಿ ಹೆಸರಿಸಬಹುದು. ಇದು ಸ್ಥಳೀಯ ಸಂಗ್ರಹವನ್ನು (ಈ ಎಲ್ಲಾ D877F783D5D3EF8C) MTProto ನಲ್ಲಿ ಸಂದೇಶಗಳ ರೀತಿಯಲ್ಲಿಯೇ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡುತ್ತದೆ (ಈ ಸಂದರ್ಭದಲ್ಲಿ ಆವೃತ್ತಿ 1.0 ರಲ್ಲಿ ಮಾತ್ರ), ಅಂದರೆ. ಮೊದಲು ಸಂದೇಶ ಕೀ, ನಂತರ ಡೇಟಾ ಸ್ವತಃ (ಮತ್ತು ಎಲ್ಲೋ ಪ್ರಮುಖ ದೊಡ್ಡದಾಗಿದೆ auth_key 256 ಬೈಟ್‌ಗಳು, ಅದು ಇಲ್ಲದೆ msg_key ಅನುಪಯುಕ್ತ). ಆದ್ದರಿಂದ, ದೊಡ್ಡ ಫೈಲ್‌ಗಳಲ್ಲಿ ಸಮಸ್ಯೆಯು ಗಮನಾರ್ಹವಾಗುತ್ತದೆ. ಅವುಗಳೆಂದರೆ, ನೀವು ಡೇಟಾದ ಎರಡು ಪ್ರತಿಗಳನ್ನು ಇಟ್ಟುಕೊಳ್ಳಬೇಕು - ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮತ್ತು ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮತ್ತು ಮೆಗಾಬೈಟ್‌ಗಳು ಅಥವಾ ಸ್ಟ್ರೀಮಿಂಗ್ ವೀಡಿಯೊ ಇದ್ದರೆ, ಉದಾಹರಣೆಗೆ? ಆದರೆ MTProto ನೊಂದಿಗೆ ನೀವು ಮಾಡಬೇಕಾಗುತ್ತದೆ ಮೊದಲಿಗೆ ಸಂಪೂರ್ಣ ಸಂದೇಶವನ್ನು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಿ ಅಥವಾ ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡಿ, ನಂತರ ಅದನ್ನು ನೆಟ್‌ವರ್ಕ್ ಅಥವಾ ಡಿಸ್ಕ್‌ಗೆ ವರ್ಗಾಯಿಸಿ. ಆದ್ದರಿಂದ, ಸಂಗ್ರಹದಲ್ಲಿರುವ ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್‌ನ ಇತ್ತೀಚಿನ ಆವೃತ್ತಿಗಳಲ್ಲಿ user_data ಮತ್ತೊಂದು ಸ್ವರೂಪವನ್ನು ಸಹ ಬಳಸಲಾಗುತ್ತದೆ - CTR ಮೋಡ್‌ನಲ್ಲಿ AES ನೊಂದಿಗೆ.

Vasily, [21.06.18 01:27] ಓಹ್, IGE ಎಂದರೇನು ಎಂದು ನಾನು ಕಂಡುಕೊಂಡೆ: IGE ಎಂಬುದು Kerberos ಗಾಗಿ "ದೃಢೀಕರಿಸುವ ಗೂಢಲಿಪೀಕರಣ ಮೋಡ್" ನಲ್ಲಿ ಮೊದಲ ಪ್ರಯತ್ನವಾಗಿದೆ. ಇದು ವಿಫಲ ಪ್ರಯತ್ನವಾಗಿದೆ (ಇದು ಸಮಗ್ರತೆಯ ರಕ್ಷಣೆಯನ್ನು ಒದಗಿಸುವುದಿಲ್ಲ), ಮತ್ತು ತೆಗೆದುಹಾಕಬೇಕಾಗಿತ್ತು. ಅದು ಕಾರ್ಯನಿರ್ವಹಿಸುವ ದೃಢೀಕರಿಸುವ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಮೋಡ್‌ಗಾಗಿ 20 ವರ್ಷಗಳ ಅನ್ವೇಷಣೆಯ ಪ್ರಾರಂಭವಾಗಿದೆ, ಇದು ಇತ್ತೀಚೆಗೆ OCB ಮತ್ತು GCM ನಂತಹ ಮೋಡ್‌ಗಳಲ್ಲಿ ಉತ್ತುಂಗಕ್ಕೇರಿತು.

ಮತ್ತು ಈಗ ಕಾರ್ಟ್ ಕಡೆಯಿಂದ ವಾದಗಳು:

ನಿಕೊಲಾಯ್ ಡುರೊವ್ ನೇತೃತ್ವದ ಟೆಲಿಗ್ರಾಮ್‌ನ ಹಿಂದಿನ ತಂಡವು ಆರು ACM ಚಾಂಪಿಯನ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿದೆ, ಅವರಲ್ಲಿ ಅರ್ಧದಷ್ಟು ಗಣಿತದಲ್ಲಿ Ph.D. MTProto ನ ಪ್ರಸ್ತುತ ಆವೃತ್ತಿಯನ್ನು ಹೊರತರಲು ಇದು ಸುಮಾರು ಎರಡು ವರ್ಷಗಳನ್ನು ತೆಗೆದುಕೊಂಡಿತು.

ಅದು ತಮಾಷೆಯಾಗಿದೆ. ಕೆಳ ಹಂತದಲ್ಲಿ ಎರಡು ವರ್ಷ

ಅಥವಾ ನೀವು ಕೇವಲ tls ತೆಗೆದುಕೊಳ್ಳಬಹುದು

ಸರಿ, ನಾವು ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಮತ್ತು ಇತರ ಸೂಕ್ಷ್ಮ ವ್ಯತ್ಯಾಸಗಳನ್ನು ಮಾಡಿದ್ದೇವೆ ಎಂದು ಹೇಳೋಣ. ಅಂತಿಮವಾಗಿ TL ನಲ್ಲಿ ಧಾರಾವಾಹಿಯಾಗಿ ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸಲು ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆಗಳನ್ನು ರದ್ದುಗೊಳಿಸಲು ಸಾಧ್ಯವೇ? ಹಾಗಾದರೆ ನೀವು ಏನು ಮತ್ತು ಹೇಗೆ ಕಳುಹಿಸಬೇಕು? ಇಲ್ಲಿ, ವಿಧಾನ ಹೇಳೋಣ init ಸಂಪರ್ಕ, ಬಹುಶಃ ಇದು ಇದೆಯೇ?

Vasily, [25.06.18 18:46] ಸಂಪರ್ಕವನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ ಮತ್ತು ಬಳಕೆದಾರರ ಸಾಧನ ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಮಾಹಿತಿಯನ್ನು ಉಳಿಸುತ್ತದೆ.

ಇದು app_id, device_model, system_version, app_version ಮತ್ತು lang_code ಅನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ.

ಮತ್ತು ಕೆಲವು ಪ್ರಶ್ನೆಗಳು

ಎಂದಿನಂತೆ ದಾಖಲೆ. ಮುಕ್ತ ಮೂಲವನ್ನು ಅಧ್ಯಯನ ಮಾಡಲು ಹಿಂಜರಿಯಬೇಡಿ

invokeWithLayer ನೊಂದಿಗೆ ಎಲ್ಲವೂ ಸರಿಸುಮಾರು ಸ್ಪಷ್ಟವಾಗಿದ್ದರೆ, ಇಲ್ಲಿ ಏನು ತಪ್ಪಾಗಿದೆ? ಇದು ತಿರುಗುತ್ತದೆ, ನಾವು ಹೊಂದಿದ್ದೇವೆ ಎಂದು ಹೇಳೋಣ - ಕ್ಲೈಂಟ್ ಈಗಾಗಲೇ ಸರ್ವರ್ ಅನ್ನು ಕೇಳಲು ಏನನ್ನಾದರೂ ಹೊಂದಿತ್ತು - ನಾವು ಕಳುಹಿಸಲು ಬಯಸಿದ ವಿನಂತಿಯಿದೆ:

ವಾಸಿಲಿ, [25.06.18 19:13] ಕೋಡ್ ಮೂಲಕ ನಿರ್ಣಯಿಸುವುದು, ಮೊದಲ ಕರೆಯನ್ನು ಈ ಅಮೇಧ್ಯದಲ್ಲಿ ಸುತ್ತಿಡಲಾಗಿದೆ ಮತ್ತು ಅಮೇಧ್ಯವನ್ನು ಸ್ವತಃ ಇನ್ವೋಕ್ವಿತ್ಲೇಯರ್ನಲ್ಲಿ ಸುತ್ತಿಡಲಾಗಿದೆ.

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 ರ ಪ್ರಸಿದ್ಧ ಘಟನೆಗಳ ನಂತರ, ಸಂಖ್ಯೆ ಗಮನಾರ್ಹವಾಗಿ ಹೆಚ್ಚಾಗಿದೆ.

ಈಗ ನಾವು ಅನಾಮಧೇಯವಾಗಿ ಸರ್ವರ್‌ನಲ್ಲಿ ಈ ಹಂತಕ್ಕೆ ಬಂದಿದ್ದೇವೆ ಎಂದು ನೆನಪಿಸಿಕೊಳ್ಳೋಣ. ಕೇವಲ ಐಪಿ ವಿಳಾಸವನ್ನು ಪಡೆಯುವುದು ತುಂಬಾ ದುಬಾರಿ ಅಲ್ಲವೇ? MTProto ನ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡದ ಭಾಗದಲ್ಲಿ ಇದನ್ನು ಮತ್ತು ಇತರ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಏಕೆ ಮಾಡಬಾರದು? ನಾನು ಆಕ್ಷೇಪಣೆಯನ್ನು ಕೇಳುತ್ತೇನೆ: "ತಪ್ಪು ವಿಳಾಸಗಳೊಂದಿಗೆ ಪ್ರತಿಕ್ರಿಯಿಸುವವರು RKN ಅಲ್ಲ ಎಂದು ನಾವು ಹೇಗೆ ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಬಹುದು?" ಇದಕ್ಕೆ ನಾವು ಸಾಮಾನ್ಯವಾಗಿ, ಅಧಿಕೃತ ಗ್ರಾಹಕರು ಎಂದು ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತೇವೆ RSA ಕೀಗಳನ್ನು ಎಂಬೆಡ್ ಮಾಡಲಾಗಿದೆ, ಅಂದರೆ ನೀವು ಕೇವಲ ಮಾಡಬಹುದು ಚಂದಾದಾರರಾಗಿ ಈ ಮಾಹಿತಿ. ವಾಸ್ತವವಾಗಿ, ಕ್ಲೈಂಟ್‌ಗಳು ಇತರ ಚಾನಲ್‌ಗಳ ಮೂಲಕ ಸ್ವೀಕರಿಸುವ ನಿರ್ಬಂಧಿಸುವಿಕೆಯನ್ನು ಬೈಪಾಸ್ ಮಾಡುವ ಮಾಹಿತಿಗಾಗಿ ಇದನ್ನು ಈಗಾಗಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ (ತಾರ್ಕಿಕವಾಗಿ, ಇದನ್ನು MTProto ನಲ್ಲಿಯೇ ಮಾಡಲಾಗುವುದಿಲ್ಲ; ನೀವು ಎಲ್ಲಿ ಸಂಪರ್ಕಿಸಬೇಕು ಎಂಬುದನ್ನು ಸಹ ತಿಳಿದುಕೊಳ್ಳಬೇಕು).

ಸರಿ. ಕ್ಲೈಂಟ್ ಅಧಿಕಾರದ ಈ ಹಂತದಲ್ಲಿ, ನಾವು ಇನ್ನೂ ಅಧಿಕೃತಗೊಂಡಿಲ್ಲ ಮತ್ತು ನಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ನೋಂದಾಯಿಸಿಲ್ಲ. ಅನಧಿಕೃತ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿರುವ ವಿಧಾನಗಳಿಗೆ ಸರ್ವರ್ ಏನು ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ನಾವು ಇದೀಗ ನೋಡಲು ಬಯಸುತ್ತೇವೆ. ಮತ್ತು ಇಲ್ಲಿ…

ವಾಸಿಲಿ, [10.07.18 14:45] https://core.telegram.org/method/help.getConfig

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

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

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

ಯೋಜನೆಯಲ್ಲಿ, ಮೊದಲನೆಯದು ಎರಡನೆಯದು

tdesktop ಸ್ಕೀಮಾದಲ್ಲಿ ಮೂರನೇ ಮೌಲ್ಯವಾಗಿದೆ

ಹೌದು, ಅಂದಿನಿಂದ, ಸಹಜವಾಗಿ, ದಸ್ತಾವೇಜನ್ನು ನವೀಕರಿಸಲಾಗಿದೆ. ಅದು ಶೀಘ್ರದಲ್ಲೇ ಮತ್ತೆ ಅಪ್ರಸ್ತುತವಾಗಬಹುದು. ಅನನುಭವಿ ಡೆವಲಪರ್ ಹೇಗೆ ತಿಳಿಯಬೇಕು? ಬಹುಶಃ ನೀವು ನಿಮ್ಮ ಅರ್ಜಿಯನ್ನು ನೋಂದಾಯಿಸಿದರೆ, ಅವರು ನಿಮಗೆ ತಿಳಿಸುತ್ತಾರೆಯೇ? ವಾಸಿಲಿ ಇದನ್ನು ಮಾಡಿದರು, ಆದರೆ ಅಯ್ಯೋ, ಅವರು ಅವನಿಗೆ ಏನನ್ನೂ ಕಳುಹಿಸಲಿಲ್ಲ (ಮತ್ತೆ, ನಾವು ಇದನ್ನು ಎರಡನೇ ಭಾಗದಲ್ಲಿ ಮಾತನಾಡುತ್ತೇವೆ).

...ನಾವು ಈಗಾಗಲೇ ಹೇಗಾದರೂ API ಗೆ ತೆರಳಿದ್ದೇವೆ ಎಂದು ನೀವು ಗಮನಿಸಿದ್ದೀರಿ, ಅಂದರೆ. ಮುಂದಿನ ಹಂತಕ್ಕೆ, ಮತ್ತು MTProto ವಿಷಯದಲ್ಲಿ ಏನಾದರೂ ತಪ್ಪಿಸಿಕೊಂಡಿರಾ? ಆಶ್ಚರ್ಯವಿಲ್ಲ:

ವಾಸಿಲಿ, [28.06.18 02:04] Mm, ಅವರು e2e ನಲ್ಲಿ ಕೆಲವು ಅಲ್ಗಾರಿದಮ್‌ಗಳ ಮೂಲಕ ಗುಜರಿ ಮಾಡುತ್ತಿದ್ದಾರೆ

Mtproto ಎರಡೂ ಡೊಮೇನ್‌ಗಳಿಗೆ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಅಲ್ಗಾರಿದಮ್‌ಗಳು ಮತ್ತು ಕೀಗಳನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ, ಜೊತೆಗೆ ಸ್ವಲ್ಪ ಹೊದಿಕೆ ರಚನೆ

ಆದರೆ ಅವು ನಿರಂತರವಾಗಿ ಸ್ಟಾಕ್‌ನ ವಿವಿಧ ಹಂತಗಳನ್ನು ಮಿಶ್ರಣ ಮಾಡುತ್ತವೆ, ಆದ್ದರಿಂದ mtproto ಎಲ್ಲಿ ಕೊನೆಗೊಂಡಿತು ಮತ್ತು ಮುಂದಿನ ಹಂತವು ಪ್ರಾರಂಭವಾಯಿತು ಎಂಬುದು ಯಾವಾಗಲೂ ಸ್ಪಷ್ಟವಾಗಿಲ್ಲ

ಅವರು ಹೇಗೆ ಮಿಶ್ರಣ ಮಾಡುತ್ತಾರೆ? ಸರಿ, PFS ಗಾಗಿ ಅದೇ ತಾತ್ಕಾಲಿಕ ಕೀ ಇಲ್ಲಿದೆ, ಉದಾಹರಣೆಗೆ (ಮೂಲಕ, ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್ಟಾಪ್ ಇದನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ). ಇದನ್ನು API ವಿನಂತಿಯಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗುತ್ತದೆ auth.bindTempAuthKey, ಅಂದರೆ ಉನ್ನತ ಮಟ್ಟದಿಂದ. ಆದರೆ ಅದೇ ಸಮಯದಲ್ಲಿ ಅದು ಕೆಳ ಮಟ್ಟದಲ್ಲಿ ಎನ್‌ಕ್ರಿಪ್ಶನ್‌ಗೆ ಅಡ್ಡಿಪಡಿಸುತ್ತದೆ - ಅದರ ನಂತರ, ಉದಾಹರಣೆಗೆ, ನೀವು ಅದನ್ನು ಮತ್ತೆ ಮಾಡಬೇಕಾಗಿದೆ initConnection ಇತ್ಯಾದಿ, ಇದು ಅಲ್ಲ ಕೇವಲ ಸಾಮಾನ್ಯ ವಿನಂತಿ. ವಿಶೇಷವೆಂದರೆ ನೀವು ಪ್ರತಿ DC ಗೆ ಕೇವಲ ಒಂದು ತಾತ್ಕಾಲಿಕ ಕೀಯನ್ನು ಹೊಂದಬಹುದು, ಆದರೂ ಕ್ಷೇತ್ರ auth_key_id ಪ್ರತಿ ಸಂದೇಶದಲ್ಲಿ ನೀವು ಕನಿಷ್ಟ ಪ್ರತಿ ಸಂದೇಶವನ್ನು ಕೀಲಿಯನ್ನು ಬದಲಾಯಿಸಲು ಅನುಮತಿಸುತ್ತದೆ, ಮತ್ತು ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ತಾತ್ಕಾಲಿಕ ಕೀಲಿಯನ್ನು "ಮರೆಯಲು" ಸರ್ವರ್ ಹಕ್ಕನ್ನು ಹೊಂದಿದೆ - ಈ ಸಂದರ್ಭದಲ್ಲಿ ಏನು ಮಾಡಬೇಕೆಂದು ದಸ್ತಾವೇಜನ್ನು ಹೇಳುವುದಿಲ್ಲ ... ಅಲ್ಲದೆ, ಏಕೆ ಸಾಧ್ಯವಾಗಲಿಲ್ಲ ಭವಿಷ್ಯದ ಲವಣಗಳ ಗುಂಪಿನಂತೆ ನೀವು ಹಲವಾರು ಕೀಗಳನ್ನು ಹೊಂದಿಲ್ಲ, ಮತ್ತು?..

MTProto ಥೀಮ್ ಬಗ್ಗೆ ಗಮನಿಸಬೇಕಾದ ಕೆಲವು ಇತರ ವಿಷಯಗಳಿವೆ.

ಸಂದೇಶ ಸಂದೇಶಗಳು, msg_id, msg_seqno, ದೃಢೀಕರಣಗಳು, ತಪ್ಪು ದಿಕ್ಕಿನಲ್ಲಿ ಪಿಂಗ್‌ಗಳು ಮತ್ತು ಇತರ ವಿಶಿಷ್ಟತೆಗಳು

ನೀವು ಅವರ ಬಗ್ಗೆ ಏಕೆ ತಿಳಿದುಕೊಳ್ಳಬೇಕು? ಏಕೆಂದರೆ ಅವರು ಉನ್ನತ ಮಟ್ಟಕ್ಕೆ "ಸೋರಿಕೆ" ಮಾಡುತ್ತಾರೆ ಮತ್ತು API ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ ನೀವು ಅವರ ಬಗ್ಗೆ ತಿಳಿದಿರಬೇಕು. ನಾವು msg_key ನಲ್ಲಿ ಆಸಕ್ತಿ ಹೊಂದಿಲ್ಲ ಎಂದು ಭಾವಿಸೋಣ; ಕೆಳಗಿನ ಹಂತವು ನಮಗೆ ಎಲ್ಲವನ್ನೂ ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡಿದೆ. ಆದರೆ ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡಿದ ಡೇಟಾದ ಒಳಗೆ ನಾವು ಈ ಕೆಳಗಿನ ಕ್ಷೇತ್ರಗಳನ್ನು ಹೊಂದಿದ್ದೇವೆ (ಡೇಟಾದ ಉದ್ದವೂ ಸಹ, ಆದ್ದರಿಂದ ಪ್ಯಾಡಿಂಗ್ ಎಲ್ಲಿದೆ ಎಂದು ನಮಗೆ ತಿಳಿದಿದೆ, ಆದರೆ ಅದು ಮುಖ್ಯವಲ್ಲ):

  • ಉಪ್ಪು - int64
  • session_id - int64
  • message_id — int64
  • seq_no - int32

ಇಡೀ ಡಿಸಿಗೆ ಒಂದೇ ಒಂದು ಉಪ್ಪು ಇದೆ ಎಂದು ನಿಮಗೆ ನೆನಪಿಸೋಣ. ಅವಳ ಬಗ್ಗೆ ಯಾಕೆ ಗೊತ್ತು? ವಿನಂತಿ ಇದೆ ಎಂಬ ಕಾರಣಕ್ಕೆ ಅಲ್ಲ get_future_salts, ಯಾವ ಮಧ್ಯಂತರಗಳು ಮಾನ್ಯವಾಗಿರುತ್ತವೆ ಎಂದು ನಿಮಗೆ ತಿಳಿಸುತ್ತದೆ, ಆದರೆ ನಿಮ್ಮ ಉಪ್ಪು "ಕೊಳೆತ" ಆಗಿದ್ದರೆ, ಸಂದೇಶವು (ವಿನಂತಿ) ಸರಳವಾಗಿ ಕಳೆದುಹೋಗುತ್ತದೆ. ಸರ್ವರ್, ಸಹಜವಾಗಿ, ಹೊಸ ಉಪ್ಪನ್ನು ನೀಡುವ ಮೂಲಕ ವರದಿ ಮಾಡುತ್ತದೆ new_session_created - ಆದರೆ ಹಳೆಯದರೊಂದಿಗೆ ನೀವು ಅದನ್ನು ಹೇಗಾದರೂ ಮರುಕಳುಹಿಸಬೇಕಾಗುತ್ತದೆ, ಉದಾಹರಣೆಗೆ. ಮತ್ತು ಈ ಸಮಸ್ಯೆಯು ಅಪ್ಲಿಕೇಶನ್ ಆರ್ಕಿಟೆಕ್ಚರ್ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ.

ಅನೇಕ ಕಾರಣಗಳಿಗಾಗಿ ಸೆಷನ್‌ಗಳನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಬಿಡಲು ಮತ್ತು ಈ ರೀತಿಯಲ್ಲಿ ಪ್ರತಿಕ್ರಿಯಿಸಲು ಸರ್ವರ್‌ಗೆ ಅನುಮತಿಸಲಾಗಿದೆ. ವಾಸ್ತವವಾಗಿ, ಕ್ಲೈಂಟ್ ಕಡೆಯಿಂದ MTProto ಸೆಷನ್ ಎಂದರೇನು? ಇವು ಎರಡು ಸಂಖ್ಯೆಗಳು session_id и seq_no ಈ ಅಧಿವೇಶನದಲ್ಲಿ ಸಂದೇಶಗಳು. ಒಳ್ಳೆಯದು, ಮತ್ತು ಆಧಾರವಾಗಿರುವ TCP ಸಂಪರ್ಕ, ಸಹಜವಾಗಿ. ನಮ್ಮ ಕ್ಲೈಂಟ್ ಇನ್ನೂ ಅನೇಕ ಕೆಲಸಗಳನ್ನು ಹೇಗೆ ಮಾಡಬೇಕೆಂದು ತಿಳಿದಿಲ್ಲ ಎಂದು ಹೇಳೋಣ, ಅವರು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿದ್ದಾರೆ ಮತ್ತು ಮರುಸಂಪರ್ಕಿಸಿದ್ದಾರೆ. ಇದು ತ್ವರಿತವಾಗಿ ಸಂಭವಿಸಿದಲ್ಲಿ - ಹಳೆಯ ಸೆಷನ್ ಹೊಸ TCP ಸಂಪರ್ಕದಲ್ಲಿ ಮುಂದುವರೆಯಿತು, ಹೆಚ್ಚಳ seq_no ಮತ್ತಷ್ಟು. ಇದು ಬಹಳ ಸಮಯ ತೆಗೆದುಕೊಂಡರೆ, ಸರ್ವರ್ ಅದನ್ನು ಅಳಿಸಬಹುದು, ಏಕೆಂದರೆ ಅದರ ಬದಿಯಲ್ಲಿ ಅದು ಸರದಿಯಾಗಿದೆ, ನಾವು ಕಂಡುಕೊಂಡಂತೆ.

ಅದು ಏನಾಗಿರಬೇಕು seq_no? ಓಹ್, ಇದು ಒಂದು ಟ್ರಿಕಿ ಪ್ರಶ್ನೆ. ಇದರ ಅರ್ಥವನ್ನು ಪ್ರಾಮಾಣಿಕವಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಪ್ರಯತ್ನಿಸಿ:

ವಿಷಯ-ಸಂಬಂಧಿತ ಸಂದೇಶ

ಸ್ಪಷ್ಟವಾದ ಸ್ವೀಕೃತಿಯ ಅಗತ್ಯವಿರುವ ಸಂದೇಶ. ಇವುಗಳು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಮತ್ತು ಅನೇಕ ಸೇವಾ ಸಂದೇಶಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತವೆ, ವಾಸ್ತವಿಕವಾಗಿ ಎಲ್ಲಾ ಕಂಟೈನರ್‌ಗಳು ಮತ್ತು ಸ್ವೀಕೃತಿಗಳನ್ನು ಹೊರತುಪಡಿಸಿ.

ಸಂದೇಶ ಅನುಕ್ರಮ ಸಂಖ್ಯೆ (msg_seqno)

32-ಬಿಟ್ ಸಂಖ್ಯೆಯು "ವಿಷಯ-ಸಂಬಂಧಿತ" ಸಂದೇಶಗಳ (ಸ್ವೀಕಾರದ ಅಗತ್ಯವಿರುವವುಗಳು ಮತ್ತು ನಿರ್ದಿಷ್ಟವಾಗಿ ಕಂಟೈನರ್‌ಗಳಲ್ಲದವುಗಳು) ಈ ಸಂದೇಶಕ್ಕೆ ಮುಂಚಿತವಾಗಿ ಕಳುಹಿಸುವವರಿಂದ ರಚಿಸಲ್ಪಟ್ಟ ಮತ್ತು ನಂತರದಲ್ಲಿ ಒಂದರಿಂದ ಹೆಚ್ಚಿಸಲಾದ ಸಂದೇಶಗಳಿಗೆ ಸಮಾನವಾಗಿರುತ್ತದೆ ವಿಷಯ-ಸಂಬಂಧಿತ ಸಂದೇಶ. ಧಾರಕವನ್ನು ಯಾವಾಗಲೂ ಅದರ ಸಂಪೂರ್ಣ ವಿಷಯಗಳ ನಂತರ ಉತ್ಪಾದಿಸಲಾಗುತ್ತದೆ; ಆದ್ದರಿಂದ, ಅದರ ಅನುಕ್ರಮ ಸಂಖ್ಯೆಯು ಅದರಲ್ಲಿ ಒಳಗೊಂಡಿರುವ ಸಂದೇಶಗಳ ಅನುಕ್ರಮ ಸಂಖ್ಯೆಗಳಿಗಿಂತ ಹೆಚ್ಚಾಗಿರುತ್ತದೆ ಅಥವಾ ಸಮಾನವಾಗಿರುತ್ತದೆ.

ಇದು ಯಾವ ರೀತಿಯ ಸರ್ಕಸ್ 1 ರಿಂದ ಹೆಚ್ಚಳ, ಮತ್ತು ಇನ್ನೊಂದು 2 ರಿಂದ? ನಿರ್ದಿಷ್ಟವಾಗಿ, ಅದು ಹೊರಬರುತ್ತದೆ, ಕಳುಹಿಸಬಹುದು ಹಲವಾರು ಒಂದೇ ರೀತಿಯ ದೃಢೀಕರಣಗಳು seq_no! ಹೇಗೆ? ಒಳ್ಳೆಯದು, ಉದಾಹರಣೆಗೆ, ಸರ್ವರ್ ನಮಗೆ ಏನನ್ನಾದರೂ ಕಳುಹಿಸುತ್ತದೆ, ಅದನ್ನು ಕಳುಹಿಸುತ್ತದೆ ಮತ್ತು ನಾವು ಮೌನವಾಗಿರುತ್ತೇವೆ, ಅದರ ಸಂದೇಶಗಳ ಸ್ವೀಕೃತಿಯನ್ನು ದೃಢೀಕರಿಸುವ ಸೇವಾ ಸಂದೇಶಗಳೊಂದಿಗೆ ಮಾತ್ರ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತೇವೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ನಮ್ಮ ಹೊರಹೋಗುವ ದೃಢೀಕರಣಗಳು ಅದೇ ಹೊರಹೋಗುವ ಸಂಖ್ಯೆಯನ್ನು ಹೊಂದಿರುತ್ತವೆ. ನೀವು TCP ಯೊಂದಿಗೆ ಪರಿಚಿತರಾಗಿದ್ದರೆ ಮತ್ತು ಇದು ಹೇಗಾದರೂ ಹುಚ್ಚುಚ್ಚಾಗಿ ತೋರುತ್ತದೆ ಎಂದು ಭಾವಿಸಿದರೆ, ಆದರೆ ಅದು ತುಂಬಾ ಕಾಡುವುದಿಲ್ಲ ಎಂದು ತೋರುತ್ತದೆ, ಏಕೆಂದರೆ TCP ಯಲ್ಲಿ seq_no ಬದಲಾಗುವುದಿಲ್ಲ, ಆದರೆ ದೃಢೀಕರಣಕ್ಕೆ ಹೋಗುತ್ತದೆ seq_no ಮತ್ತೊಂದೆಡೆ, ನಾನು ನಿಮ್ಮನ್ನು ಅಸಮಾಧಾನಗೊಳಿಸಲು ಆತುರಪಡುತ್ತೇನೆ. MTProto ನಲ್ಲಿ ದೃಢೀಕರಣಗಳನ್ನು ಒದಗಿಸಲಾಗಿದೆ ಅಲ್ಲ ಮೇಲೆ seq_no, TCP ಯಲ್ಲಿರುವಂತೆ, ಆದರೆ ಮೂಲಕ msg_id !

ಇದು ಏನು msg_id, ಈ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ಪ್ರಮುಖವಾದವುಗಳು? ಹೆಸರೇ ಸೂಚಿಸುವಂತೆ ಅನನ್ಯ ಸಂದೇಶ ಗುರುತಿಸುವಿಕೆ. ಇದನ್ನು 64-ಬಿಟ್ ಸಂಖ್ಯೆ ಎಂದು ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ, ಅದರಲ್ಲಿ ಕಡಿಮೆ ಬಿಟ್‌ಗಳು ಮತ್ತೊಮ್ಮೆ "ಸರ್ವರ್-ನಾಟ್-ಸರ್ವರ್" ಮ್ಯಾಜಿಕ್ ಅನ್ನು ಹೊಂದಿವೆ, ಮತ್ತು ಉಳಿದವು ಯುನಿಕ್ಸ್ ಟೈಮ್‌ಸ್ಟ್ಯಾಂಪ್ ಆಗಿದ್ದು, ಫ್ರಾಕ್ಷನಲ್ ಭಾಗವನ್ನು ಒಳಗೊಂಡಂತೆ 32 ಬಿಟ್‌ಗಳನ್ನು ಎಡಕ್ಕೆ ವರ್ಗಾಯಿಸಲಾಗಿದೆ. ಆ. ಟೈಮ್‌ಸ್ಟ್ಯಾಂಪ್ ಪ್ರತಿ ಸೆ (ಮತ್ತು ಹೆಚ್ಚು ವ್ಯತ್ಯಾಸವಿರುವ ಸಮಯಗಳೊಂದಿಗೆ ಸಂದೇಶಗಳನ್ನು ಸರ್ವರ್ ತಿರಸ್ಕರಿಸುತ್ತದೆ). ಇದರಿಂದ ಸಾಮಾನ್ಯವಾಗಿ ಇದು ಕ್ಲೈಂಟ್‌ಗೆ ಜಾಗತಿಕವಾಗಿರುವ ಗುರುತಿಸುವಿಕೆ ಎಂದು ತಿರುಗುತ್ತದೆ. ಅದನ್ನು ನೀಡಲಾಗಿದೆ - ನಾವು ನೆನಪಿಟ್ಟುಕೊಳ್ಳೋಣ session_id - ನಮಗೆ ಭರವಸೆ ಇದೆ: ಯಾವುದೇ ಸಂದರ್ಭದಲ್ಲೂ ಒಂದು ಸೆಷನ್‌ಗೆ ಮೀಸಲಾದ ಸಂದೇಶವನ್ನು ಬೇರೆ ಸೆಷನ್‌ಗೆ ಕಳುಹಿಸಲಾಗುವುದಿಲ್ಲ. ಅಂದರೆ, ಈಗಾಗಲೇ ಇದೆ ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ ಮೂರು ಮಟ್ಟ - ಅಧಿವೇಶನ, ಅಧಿವೇಶನ ಸಂಖ್ಯೆ, ಸಂದೇಶ ಐಡಿ. ಏಕೆ ಇಂತಹ ಮಿತಿಮೀರಿದ, ಈ ರಹಸ್ಯ ಬಹಳ ದೊಡ್ಡದಾಗಿದೆ.

ಆದ್ದರಿಂದ, msg_id ಇದಕ್ಕೆ ಅಗತ್ಯವಿದೆ...

RPC: ವಿನಂತಿಗಳು, ಪ್ರತಿಕ್ರಿಯೆಗಳು, ದೋಷಗಳು. ದೃಢೀಕರಣಗಳು.

ನೀವು ಗಮನಿಸಿರುವಂತೆ, ಯಾವುದೇ ವಿಶೇಷವಾದ "ಆರ್‌ಪಿಸಿ ವಿನಂತಿಯನ್ನು ಮಾಡು" ಪ್ರಕಾರವಿಲ್ಲ ಅಥವಾ ರೇಖಾಚಿತ್ರದಲ್ಲಿ ಎಲ್ಲಿಯೂ ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ, ಆದರೂ ಉತ್ತರಗಳಿವೆ. ಎಲ್ಲಾ ನಂತರ, ನಾವು ವಿಷಯ-ಸಂಬಂಧಿತ ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿದ್ದೇವೆ! ಅದು, ಯಾವುದೇ ಸಂದೇಶವು ವಿನಂತಿಯಾಗಿರಬಹುದು! ಅಥವಾ ಇರಬಾರದು. ಎಲ್ಲಾ ನಂತರ, ಪ್ರತಿಯೊಂದರಲ್ಲೂ ಆಗಿದೆ msg_id. ಆದರೆ ಉತ್ತರಗಳಿವೆ:

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

ಇದು ಯಾವ ಸಂದೇಶಕ್ಕೆ ಪ್ರತಿಕ್ರಿಯೆಯಾಗಿದೆ ಎಂಬುದನ್ನು ಇಲ್ಲಿ ಸೂಚಿಸಲಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ, API ಯ ಉನ್ನತ ಮಟ್ಟದಲ್ಲಿ, ನಿಮ್ಮ ವಿನಂತಿಯ ಸಂಖ್ಯೆ ಏನೆಂದು ನೀವು ನೆನಪಿಟ್ಟುಕೊಳ್ಳಬೇಕು - ಕೆಲಸವು ಅಸಮಕಾಲಿಕವಾಗಿದೆ ಎಂದು ವಿವರಿಸುವ ಅಗತ್ಯವಿಲ್ಲ ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ ಮತ್ತು ಅದೇ ಸಮಯದಲ್ಲಿ ಹಲವಾರು ವಿನಂತಿಗಳು ಪ್ರಗತಿಯಲ್ಲಿವೆ, ಉತ್ತರಗಳನ್ನು ಯಾವುದೇ ಕ್ರಮದಲ್ಲಿ ಹಿಂತಿರುಗಿಸಬಹುದು? ತಾತ್ವಿಕವಾಗಿ, ಇದರಿಂದ ಮತ್ತು ಕೆಲಸಗಾರರಿಲ್ಲದಂತಹ ದೋಷ ಸಂದೇಶಗಳಿಂದ, ಇದರ ಹಿಂದಿನ ಆರ್ಕಿಟೆಕ್ಚರ್ ಅನ್ನು ಕಂಡುಹಿಡಿಯಬಹುದು: ನಿಮ್ಮೊಂದಿಗೆ TCP ಸಂಪರ್ಕವನ್ನು ನಿರ್ವಹಿಸುವ ಸರ್ವರ್ ಫ್ರಂಟ್-ಎಂಡ್ ಬ್ಯಾಲೆನ್ಸರ್ ಆಗಿದೆ, ಇದು ಬ್ಯಾಕೆಂಡ್‌ಗಳಿಗೆ ವಿನಂತಿಗಳನ್ನು ಫಾರ್ವರ್ಡ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಮೂಲಕ ಅವುಗಳನ್ನು ಮರಳಿ ಸಂಗ್ರಹಿಸುತ್ತದೆ message_id. ಇಲ್ಲಿ ಎಲ್ಲವೂ ಸ್ಪಷ್ಟ, ತಾರ್ಕಿಕ ಮತ್ತು ಒಳ್ಳೆಯದು ಎಂದು ತೋರುತ್ತದೆ.

ಹೌದು?.. ಮತ್ತು ನೀವು ಅದರ ಬಗ್ಗೆ ಯೋಚಿಸಿದರೆ? ಎಲ್ಲಾ ನಂತರ, RPC ಪ್ರತಿಕ್ರಿಯೆಯು ಸ್ವತಃ ಕ್ಷೇತ್ರವನ್ನು ಹೊಂದಿದೆ msg_id! “ನೀವು ನನ್ನ ಉತ್ತರಕ್ಕೆ ಉತ್ತರಿಸುತ್ತಿಲ್ಲ!” ಎಂದು ನಾವು ಸರ್ವರ್‌ನಲ್ಲಿ ಕೂಗಬೇಕೇ? ಮತ್ತು ಹೌದು, ದೃಢೀಕರಣಗಳ ಬಗ್ಗೆ ಏನು ಇತ್ತು? ಪುಟದ ಬಗ್ಗೆ ಸಂದೇಶಗಳ ಬಗ್ಗೆ ಸಂದೇಶಗಳು ಏನೆಂದು ನಮಗೆ ಹೇಳುತ್ತದೆ

msgs_ack#62d6b459 msg_ids:Vector long = MsgsAck;

ಮತ್ತು ಅದನ್ನು ಪ್ರತಿ ಬದಿಯಿಂದ ಮಾಡಬೇಕು. ಆದರೆ ಯಾವಾಗಲೂ ಅಲ್ಲ! ನೀವು RpcResult ಅನ್ನು ಸ್ವೀಕರಿಸಿದರೆ, ಅದು ಸ್ವತಃ ದೃಢೀಕರಣವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಅಂದರೆ, ಸರ್ವರ್ ನಿಮ್ಮ ವಿನಂತಿಗೆ MsgsAck ಮೂಲಕ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು - "ನಾನು ಅದನ್ನು ಸ್ವೀಕರಿಸಿದ್ದೇನೆ." RpcResult ತಕ್ಷಣವೇ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು. ಇದು ಎರಡೂ ಆಗಿರಬಹುದು.

ಮತ್ತು ಹೌದು, ನೀವು ಇನ್ನೂ ಉತ್ತರವನ್ನು ಉತ್ತರಿಸಬೇಕಾಗಿದೆ! ದೃಢೀಕರಣ. ಇಲ್ಲದಿದ್ದರೆ, ಸರ್ವರ್ ಅದನ್ನು ವಿತರಿಸಲಾಗುವುದಿಲ್ಲ ಎಂದು ಪರಿಗಣಿಸುತ್ತದೆ ಮತ್ತು ಅದನ್ನು ನಿಮಗೆ ಮತ್ತೆ ಕಳುಹಿಸುತ್ತದೆ. ಮರುಸಂಪರ್ಕದ ನಂತರವೂ. ಆದರೆ ಇಲ್ಲಿ, ಸಹಜವಾಗಿ, ಸಮಯಾವಧಿಯ ಸಮಸ್ಯೆ ಉದ್ಭವಿಸುತ್ತದೆ. ಅವುಗಳನ್ನು ಸ್ವಲ್ಪ ನಂತರ ನೋಡೋಣ.

ಈ ಮಧ್ಯೆ, ಸಂಭವನೀಯ ಪ್ರಶ್ನೆ ಎಕ್ಸಿಕ್ಯೂಶನ್ ದೋಷಗಳನ್ನು ನೋಡೋಣ.

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

ಓಹ್, ಯಾರಾದರೂ ಉದ್ಗರಿಸುತ್ತಾರೆ, ಇಲ್ಲಿ ಹೆಚ್ಚು ಮಾನವೀಯ ಸ್ವರೂಪವಿದೆ - ಒಂದು ಸಾಲು ಇದೆ! ನಿಮ್ಮ ಸಮಯ ತೆಗೆದುಕೊಳ್ಳಿ. ಇಲ್ಲಿ ದೋಷಗಳ ಪಟ್ಟಿ, ಆದರೆ ಸಹಜವಾಗಿ ಪೂರ್ಣವಾಗಿಲ್ಲ. ಅದರಿಂದ ನಾವು ಕೋಡ್ ಎಂದು ತಿಳಿಯುತ್ತೇವೆ ಏನೋ ಹಾಗೆ HTTP ದೋಷಗಳು (ಅಲ್ಲದೆ, ಸಹಜವಾಗಿ, ಪ್ರತಿಕ್ರಿಯೆಗಳ ಶಬ್ದಾರ್ಥವನ್ನು ಗೌರವಿಸಲಾಗುವುದಿಲ್ಲ, ಕೆಲವು ಸ್ಥಳಗಳಲ್ಲಿ ಅವುಗಳನ್ನು ಯಾದೃಚ್ಛಿಕವಾಗಿ ಕೋಡ್‌ಗಳ ನಡುವೆ ವಿತರಿಸಲಾಗುತ್ತದೆ), ಮತ್ತು ಸಾಲು ಈ ರೀತಿ ಕಾಣುತ್ತದೆ CAPITAL_LETTERS_AND_NUMBERS. ಉದಾಹರಣೆಗೆ, PHONE_NUMBER_OCCUPIED ಅಥವಾ FILE_PART_Х_MISSING. ಸರಿ, ಅಂದರೆ, ನಿಮಗೆ ಇನ್ನೂ ಈ ಸಾಲು ಬೇಕಾಗುತ್ತದೆ ಪಾರ್ಸ್. ಉದಾಹರಣೆಗೆ FLOOD_WAIT_3600 ನೀವು ಒಂದು ಗಂಟೆ ಕಾಯಬೇಕು ಎಂದು ಅರ್ಥ, ಮತ್ತು PHONE_MIGRATE_5, ಈ ಪೂರ್ವಪ್ರತ್ಯಯದೊಂದಿಗೆ ದೂರವಾಣಿ ಸಂಖ್ಯೆಯನ್ನು 5ನೇ DC ಯಲ್ಲಿ ನೋಂದಾಯಿಸಬೇಕು. ನಮಗೆ ಒಂದು ರೀತಿಯ ಭಾಷೆ ಇದೆ, ಸರಿ? ನಮಗೆ ಸ್ಟ್ರಿಂಗ್‌ನಿಂದ ವಾದ ಅಗತ್ಯವಿಲ್ಲ, ಸಾಮಾನ್ಯವಾದವರು ಮಾಡುತ್ತಾರೆ, ಸರಿ.

ಮತ್ತೊಮ್ಮೆ, ಇದು ಸೇವಾ ಸಂದೇಶಗಳ ಪುಟದಲ್ಲಿಲ್ಲ, ಆದರೆ, ಈ ಯೋಜನೆಯೊಂದಿಗೆ ಈಗಾಗಲೇ ಎಂದಿನಂತೆ, ಮಾಹಿತಿಯನ್ನು ಕಾಣಬಹುದು ಮತ್ತೊಂದು ದಸ್ತಾವೇಜನ್ನು ಪುಟದಲ್ಲಿ. ಅಥವಾ ಅನುಮಾನ ಮೂಡಿಸಿದರು. ಮೊದಲನೆಯದಾಗಿ, ನೋಡಿ, ಟೈಪಿಂಗ್/ಲೇಯರ್ ಉಲ್ಲಂಘನೆ - RpcError ಗೂಡುಕಟ್ಟಬಹುದು RpcResult. ಏಕೆ ಹೊರಗೆ ಇಲ್ಲ? ನಾವೇನು ​​ಲೆಕ್ಕಕ್ಕೆ ತೆಗೆದುಕೊಳ್ಳಲಿಲ್ಲ?.. ಅದಕ್ಕೆ ತಕ್ಕಂತೆ ಎಲ್ಲಿ ಗ್ಯಾರಂಟಿ RpcError ಎಂಬೆಡ್ ಮಾಡದಿರಬಹುದು RpcResult, ಆದರೆ ನೇರವಾಗಿ ಅಥವಾ ಇನ್ನೊಂದು ಪ್ರಕಾರದಲ್ಲಿ ಗೂಡುಕಟ್ಟಲಾಗಿದೆಯೇ?.. ಮತ್ತು ಅದು ಸಾಧ್ಯವಾಗದಿದ್ದರೆ, ಅದು ಉನ್ನತ ಮಟ್ಟದಲ್ಲಿ ಏಕೆ ಇಲ್ಲ, ಅಂದರೆ. ಅದು ಕಾಣೆಯಾಗಿದೆ req_msg_id ? ..

ಆದರೆ ಸೇವಾ ಸಂದೇಶಗಳ ಬಗ್ಗೆ ಮುಂದುವರಿಯೋಣ. ಸರ್ವರ್ ದೀರ್ಘಕಾಲ ಯೋಚಿಸುತ್ತಿದೆ ಎಂದು ಕ್ಲೈಂಟ್ ಭಾವಿಸಬಹುದು ಮತ್ತು ಈ ಅದ್ಭುತ ವಿನಂತಿಯನ್ನು ಮಾಡಬಹುದು:

rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;

ಈ ಪ್ರಶ್ನೆಗೆ ಮೂರು ಸಂಭವನೀಯ ಉತ್ತರಗಳಿವೆ, ಮತ್ತೊಮ್ಮೆ ದೃಢೀಕರಣ ಕಾರ್ಯವಿಧಾನದೊಂದಿಗೆ ಛೇದಿಸುತ್ತದೆ; ಅವರು ಏನಾಗಿರಬೇಕು ಎಂಬುದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಪ್ರಯತ್ನಿಸುತ್ತಿದ್ದಾರೆ (ಮತ್ತು ದೃಢೀಕರಣದ ಅಗತ್ಯವಿಲ್ಲದ ಪ್ರಕಾರಗಳ ಸಾಮಾನ್ಯ ಪಟ್ಟಿ ಯಾವುದು) ಓದುಗರಿಗೆ ಮನೆಕೆಲಸವಾಗಿ ಬಿಡಲಾಗುತ್ತದೆ (ಗಮನಿಸಿ: ಮಾಹಿತಿ ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್ ಮೂಲ ಕೋಡ್ ಪೂರ್ಣಗೊಂಡಿಲ್ಲ).

ಮಾದಕ ವ್ಯಸನ: ಸಂದೇಶ ಸ್ಥಿತಿಗಳು

ಸಾಮಾನ್ಯವಾಗಿ, TL, MTProto ಮತ್ತು ಟೆಲಿಗ್ರಾಮ್‌ನಲ್ಲಿನ ಅನೇಕ ಸ್ಥಳಗಳು ಸಾಮಾನ್ಯವಾಗಿ ಮೊಂಡುತನದ ಭಾವನೆಯನ್ನು ಬಿಡುತ್ತವೆ, ಆದರೆ ಸಭ್ಯತೆ, ಚಾತುರ್ಯ ಮತ್ತು ಇತರರಿಂದ ಮೃದು ಕೌಶಲ್ಯಗಳು ನಾವು ಅದರ ಬಗ್ಗೆ ನಯವಾಗಿ ಮೌನವಾಗಿದ್ದೆವು ಮತ್ತು ಡೈಲಾಗ್‌ಗಳಲ್ಲಿನ ಅಶ್ಲೀಲತೆಯನ್ನು ಸೆನ್ಸಾರ್ ಮಾಡಿದೆವು. ಆದಾಗ್ಯೂ, ಈ ಸ್ಥಳОಪುಟದ ಬಹುಪಾಲು ಸುಮಾರು ಸಂದೇಶಗಳ ಬಗ್ಗೆ ಸಂದೇಶಗಳು ದೀರ್ಘಕಾಲದವರೆಗೆ ನೆಟ್‌ವರ್ಕ್ ಪ್ರೋಟೋಕಾಲ್‌ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುತ್ತಿರುವ ಮತ್ತು ವಿವಿಧ ಹಂತದ ವಕ್ರತೆಯ ಬೈಸಿಕಲ್‌ಗಳನ್ನು ನೋಡಿರುವ ನನಗೂ ಇದು ಆಘಾತಕಾರಿಯಾಗಿದೆ.

ಇದು ದೃಢೀಕರಣಗಳೊಂದಿಗೆ ನಿರುಪದ್ರವವಾಗಿ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ. ಮುಂದೆ ಅವರು ನಮಗೆ ಬಗ್ಗೆ ಹೇಳುತ್ತಾರೆ

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

ಸರಿ, MTProto ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ಪ್ರಾರಂಭಿಸುವ ಪ್ರತಿಯೊಬ್ಬರೂ ಅವರೊಂದಿಗೆ ವ್ಯವಹರಿಸಬೇಕು; "ಸರಿಪಡಿಸಿದ - ಮರುಸಂಕಲಿಸಿದ - ಪ್ರಾರಂಭಿಸಲಾದ" ಚಕ್ರದಲ್ಲಿ, ಸಂಪಾದನೆಗಳ ಸಮಯದಲ್ಲಿ ಕೆಟ್ಟದಾಗಿ ಹೋಗಲು ನಿರ್ವಹಿಸಿದ ಸಂಖ್ಯೆಯ ದೋಷಗಳು ಅಥವಾ ಉಪ್ಪನ್ನು ಪಡೆಯುವುದು ಸಾಮಾನ್ಯ ವಿಷಯವಾಗಿದೆ. ಆದಾಗ್ಯೂ, ಇಲ್ಲಿ ಎರಡು ಅಂಶಗಳಿವೆ:

  1. ಇದರರ್ಥ ಮೂಲ ಸಂದೇಶವು ಕಳೆದುಹೋಗಿದೆ. ನಾವು ಕೆಲವು ಸಾಲುಗಳನ್ನು ರಚಿಸಬೇಕಾಗಿದೆ, ನಾವು ಅದನ್ನು ನಂತರ ನೋಡೋಣ.
  2. ಈ ವಿಚಿತ್ರ ದೋಷ ಸಂಖ್ಯೆಗಳು ಯಾವುವು? 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 64... ಇತರ ಸಂಖ್ಯೆಗಳು ಎಲ್ಲಿವೆ, ಟಾಮಿ?

ದಸ್ತಾವೇಜನ್ನು ಹೇಳುತ್ತದೆ:

ಉದ್ದೇಶವೆಂದರೆ ದೋಷ_ಕೋಡ್ ಮೌಲ್ಯಗಳನ್ನು ಗುಂಪು ಮಾಡಲಾಗಿದೆ (error_code >> 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 ನಂತೆ ಸರಳವಾಗಿಲ್ಲ - ಇದು (ತುಲನಾತ್ಮಕವಾಗಿ) ತಾರ್ಕಿಕವಾಗಿ ಪ್ರತ್ಯೇಕವಾದ ಭಾಗವಲ್ಲ, ಆದರೆ ಅಪ್ಲಿಕೇಶನ್ ಆರ್ಕಿಟೆಕ್ಚರ್‌ಗೆ ಕಟ್ಟಲಾದ ತುಣುಕು, ಅಂದರೆ. ಅಪ್ಲಿಕೇಶನ್ ಕೋಡ್ ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಹೆಚ್ಚು ಸಮಯ ಬೇಕಾಗುತ್ತದೆ.

ಪಿಂಗ್ಗಳು ಮತ್ತು ಸಮಯಗಳು. ಸಾಲುಗಳು.

ಎಲ್ಲದರಿಂದಲೂ, ಸರ್ವರ್ ಆರ್ಕಿಟೆಕ್ಚರ್ (ಬ್ಯಾಕೆಂಡ್‌ಗಳಾದ್ಯಂತ ವಿನಂತಿಗಳ ವಿತರಣೆ) ಕುರಿತು ನಾವು ಊಹೆಗಳನ್ನು ನೆನಪಿಸಿಕೊಂಡರೆ, ಬದಲಿಗೆ ದುಃಖದ ವಿಷಯ ಅನುಸರಿಸುತ್ತದೆ - TCP ಯಲ್ಲಿನ ಎಲ್ಲಾ ವಿತರಣಾ ಖಾತರಿಗಳ ಹೊರತಾಗಿಯೂ (ಡೇಟಾವನ್ನು ತಲುಪಿಸಲಾಗುತ್ತದೆ, ಅಥವಾ ಅಂತರದ ಬಗ್ಗೆ ನಿಮಗೆ ತಿಳಿಸಲಾಗುತ್ತದೆ, ಆದರೆ ಸಮಸ್ಯೆ ಸಂಭವಿಸುವ ಮೊದಲು ಡೇಟಾವನ್ನು ತಲುಪಿಸಲಾಗುತ್ತದೆ), MTProto ನಲ್ಲಿಯೇ ದೃಢೀಕರಣಗಳು - ಯಾವುದೇ ಗ್ಯಾರಂಟಿಗಳಿಲ್ಲ. ಸರ್ವರ್ ಸುಲಭವಾಗಿ ನಿಮ್ಮ ಸಂದೇಶವನ್ನು ಕಳೆದುಕೊಳ್ಳಬಹುದು ಅಥವಾ ಹೊರಹಾಕಬಹುದು, ಮತ್ತು ಅದರ ಬಗ್ಗೆ ಏನನ್ನೂ ಮಾಡಲಾಗುವುದಿಲ್ಲ, ವಿವಿಧ ರೀತಿಯ ಊರುಗೋಲುಗಳನ್ನು ಬಳಸಿ.

ಮತ್ತು ಮೊದಲನೆಯದಾಗಿ - ಸಂದೇಶ ಸಾಲುಗಳು. ಒಳ್ಳೆಯದು, ಒಂದು ವಿಷಯದೊಂದಿಗೆ ಎಲ್ಲವೂ ಮೊದಲಿನಿಂದಲೂ ಸ್ಪಷ್ಟವಾಗಿತ್ತು - ದೃಢೀಕರಿಸದ ಸಂದೇಶವನ್ನು ಸಂಗ್ರಹಿಸಬೇಕು ಮತ್ತು ಮರುಹೊಂದಿಸಬೇಕು. ಮತ್ತು ಯಾವ ಸಮಯದ ನಂತರ? ಮತ್ತು ಹಾಸ್ಯಗಾರನು ಅವನನ್ನು ತಿಳಿದಿದ್ದಾನೆ. ಬಹುಶಃ ಆ ವ್ಯಸನಿ ಸೇವಾ ಸಂದೇಶಗಳು ಊರುಗೋಲುಗಳೊಂದಿಗೆ ಈ ಸಮಸ್ಯೆಯನ್ನು ಹೇಗಾದರೂ ಪರಿಹರಿಸುತ್ತವೆ, ಹೇಳಿ, ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್‌ನಲ್ಲಿ ಅವುಗಳಿಗೆ ಅನುಗುಣವಾದ ಸುಮಾರು 4 ಕ್ಯೂಗಳಿವೆ (ಬಹುಶಃ ಹೆಚ್ಚು, ಈಗಾಗಲೇ ಹೇಳಿದಂತೆ, ಇದಕ್ಕಾಗಿ ನೀವು ಅದರ ಕೋಡ್ ಮತ್ತು ವಾಸ್ತುಶಿಲ್ಪವನ್ನು ಹೆಚ್ಚು ಗಂಭೀರವಾಗಿ ಪರಿಶೀಲಿಸಬೇಕು; ಅದೇ ಸಮಯದಲ್ಲಿ ಸಮಯ, ಅದನ್ನು ಮಾದರಿಯಾಗಿ ತೆಗೆದುಕೊಳ್ಳಲಾಗುವುದಿಲ್ಲ ಎಂದು ನಮಗೆ ತಿಳಿದಿದೆ; MTProto ಯೋಜನೆಯಿಂದ ನಿರ್ದಿಷ್ಟ ಸಂಖ್ಯೆಯ ಪ್ರಕಾರಗಳನ್ನು ಅದರಲ್ಲಿ ಬಳಸಲಾಗುವುದಿಲ್ಲ).

ಇದು ಏಕೆ ನಡೆಯುತ್ತಿದೆ? ಬಹುಶಃ, ಸರ್ವರ್ ಪ್ರೋಗ್ರಾಮರ್‌ಗಳು ಕ್ಲಸ್ಟರ್‌ನೊಳಗೆ ವಿಶ್ವಾಸಾರ್ಹತೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ, ಅಥವಾ ಮುಂಭಾಗದ ಬ್ಯಾಲೆನ್ಸರ್‌ನಲ್ಲಿ ಬಫರಿಂಗ್ ಅನ್ನು ಸಹ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ ಮತ್ತು ಈ ಸಮಸ್ಯೆಯನ್ನು ಕ್ಲೈಂಟ್‌ಗೆ ವರ್ಗಾಯಿಸಿದರು. ಹತಾಶೆಯಿಂದ, ವಾಸಿಲಿ ಪರ್ಯಾಯ ಆಯ್ಕೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸಿದರು, ಕೇವಲ ಎರಡು ಸರತಿ ಸಾಲುಗಳೊಂದಿಗೆ, TCP ಯಿಂದ ಅಲ್ಗಾರಿದಮ್‌ಗಳನ್ನು ಬಳಸಿ - RTT ಅನ್ನು ಸರ್ವರ್‌ಗೆ ಅಳೆಯುವುದು ಮತ್ತು ದೃಢೀಕರಿಸದ ವಿನಂತಿಗಳ ಸಂಖ್ಯೆಯನ್ನು ಅವಲಂಬಿಸಿ "ವಿಂಡೋ" (ಸಂದೇಶಗಳಲ್ಲಿ) ಗಾತ್ರವನ್ನು ಸರಿಹೊಂದಿಸುವುದು. ಅಂದರೆ, ಸರ್ವರ್‌ನ ಲೋಡ್ ಅನ್ನು ನಿರ್ಣಯಿಸಲು ಅಂತಹ ಒರಟು ಹ್ಯೂರಿಸ್ಟಿಕ್ ಎಂದರೆ ಅದು ನಮ್ಮ ಎಷ್ಟು ವಿನಂತಿಗಳನ್ನು ಒಂದೇ ಸಮಯದಲ್ಲಿ ಅಗಿಯಬಹುದು ಮತ್ತು ಕಳೆದುಕೊಳ್ಳುವುದಿಲ್ಲ.

ಸರಿ, ಅಂದರೆ, ನೀವು ಅರ್ಥಮಾಡಿಕೊಂಡಿದ್ದೀರಿ, ಸರಿ? TCP ಯಲ್ಲಿ ಚಾಲನೆಯಲ್ಲಿರುವ ಪ್ರೋಟೋಕಾಲ್‌ನ ಮೇಲೆ ನೀವು TCP ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಕಾರ್ಯಗತಗೊಳಿಸಬೇಕಾದರೆ, ಇದು ತುಂಬಾ ಕಳಪೆಯಾಗಿ ವಿನ್ಯಾಸಗೊಳಿಸಲಾದ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಸೂಚಿಸುತ್ತದೆ.

ಓಹ್, ನಿಮಗೆ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ಸರತಿ ಏಕೆ ಬೇಕು ಮತ್ತು ಉನ್ನತ ಮಟ್ಟದ API ಯೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವ ವ್ಯಕ್ತಿಗೆ ಇದರ ಅರ್ಥವೇನು? ನೋಡಿ, ನೀವು ವಿನಂತಿಯನ್ನು ಮಾಡುತ್ತೀರಿ, ಅದನ್ನು ಧಾರಾವಾಹಿ ಮಾಡಿ, ಆದರೆ ನೀವು ಅದನ್ನು ತಕ್ಷಣವೇ ಕಳುಹಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಏಕೆ? ಏಕೆಂದರೆ ಉತ್ತರ ಇರುತ್ತದೆ msg_id, ಇದು ತಾತ್ಕಾಲಿಕаನಾನು ಲೇಬಲ್ ಆಗಿದ್ದೇನೆ, ಅದರ ನಿಯೋಜನೆಯನ್ನು ಸಾಧ್ಯವಾದಷ್ಟು ತಡವಾಗಿ ಮುಂದೂಡುವುದು ಉತ್ತಮ - ಒಂದು ವೇಳೆ ನಮ್ಮ ಮತ್ತು ಅವನ ನಡುವಿನ ಸಮಯದ ಹೊಂದಾಣಿಕೆಯಿಲ್ಲದ ಕಾರಣ ಸರ್ವರ್ ಅದನ್ನು ತಿರಸ್ಕರಿಸಿದರೆ (ಸಹಜವಾಗಿ, ನಾವು ನಮ್ಮ ಸಮಯವನ್ನು ವರ್ತಮಾನದಿಂದ ಬದಲಾಯಿಸುವ ಊರುಗೋಲನ್ನು ಮಾಡಬಹುದು ಸರ್ವರ್‌ನ ಪ್ರತಿಕ್ರಿಯೆಗಳಿಂದ ಲೆಕ್ಕಹಾಕಿದ ಡೆಲ್ಟಾವನ್ನು ಸೇರಿಸುವ ಮೂಲಕ ಸರ್ವರ್‌ಗೆ - ಅಧಿಕೃತ ಕ್ಲೈಂಟ್‌ಗಳು ಇದನ್ನು ಮಾಡುತ್ತಾರೆ, ಆದರೆ ಬಫರಿಂಗ್‌ನಿಂದಾಗಿ ಇದು ಕಚ್ಚಾ ಮತ್ತು ನಿಖರವಾಗಿಲ್ಲ). ಆದ್ದರಿಂದ, ನೀವು ಲೈಬ್ರರಿಯಿಂದ ಸ್ಥಳೀಯ ಕಾರ್ಯದ ಕರೆಯೊಂದಿಗೆ ವಿನಂತಿಯನ್ನು ಮಾಡಿದಾಗ, ಸಂದೇಶವು ಈ ಕೆಳಗಿನ ಹಂತಗಳ ಮೂಲಕ ಹೋಗುತ್ತದೆ:

  1. ಇದು ಒಂದು ಸರದಿಯಲ್ಲಿದೆ ಮತ್ತು ಎನ್‌ಕ್ರಿಪ್ಶನ್‌ಗಾಗಿ ಕಾಯುತ್ತಿದೆ.
  2. ನೇಮಕ ಮಾಡಲಾಗಿದೆ msg_id ಮತ್ತು ಸಂದೇಶವು ಮತ್ತೊಂದು ಸರತಿಗೆ ಹೋಯಿತು - ಸಂಭವನೀಯ ಫಾರ್ವರ್ಡ್ ಮಾಡುವಿಕೆ; ಸಾಕೆಟ್ಗೆ ಕಳುಹಿಸಿ.
  3. ಎ) ಸರ್ವರ್ MsgsAck ಗೆ ಪ್ರತಿಕ್ರಿಯಿಸಿದೆ - ಸಂದೇಶವನ್ನು ತಲುಪಿಸಲಾಗಿದೆ, ನಾವು ಅದನ್ನು "ಇತರ ಕ್ಯೂ" ನಿಂದ ಅಳಿಸುತ್ತೇವೆ.
    ಬಿ) ಅಥವಾ ಪ್ರತಿಯಾಗಿ, ಅವರು ಏನನ್ನಾದರೂ ಇಷ್ಟಪಡಲಿಲ್ಲ, ಅವರು ಬ್ಯಾಡ್ಮ್ಸ್ಗೆ ಉತ್ತರಿಸಿದರು - "ಮತ್ತೊಂದು ಕ್ಯೂ" ನಿಂದ ಮರುಕಳುಹಿಸಿ
    ಸಿ) ಏನೂ ತಿಳಿದಿಲ್ಲ, ಸಂದೇಶವನ್ನು ಮತ್ತೊಂದು ಸರದಿಯಿಂದ ಮರುಕಳುಹಿಸಬೇಕಾಗಿದೆ - ಆದರೆ ಅದು ಯಾವಾಗ ಎಂದು ನಿಖರವಾಗಿ ತಿಳಿದಿಲ್ಲ.
  4. ಸರ್ವರ್ ಅಂತಿಮವಾಗಿ ಪ್ರತಿಕ್ರಿಯಿಸಿತು RpcResult - ನಿಜವಾದ ಪ್ರತಿಕ್ರಿಯೆ (ಅಥವಾ ದೋಷ) - ಕೇವಲ ವಿತರಿಸಲಾಗಿಲ್ಲ, ಆದರೆ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲಾಗಿದೆ.

ಬಹುಶಃ, ಧಾರಕಗಳ ಬಳಕೆಯು ಸಮಸ್ಯೆಯನ್ನು ಭಾಗಶಃ ಪರಿಹರಿಸಬಹುದು. ಸಂದೇಶಗಳ ಗುಂಪನ್ನು ಒಂದರಲ್ಲಿ ಪ್ಯಾಕ್ ಮಾಡಿದಾಗ, ಮತ್ತು ಸರ್ವರ್ ಎಲ್ಲರಿಗೂ ಒಂದೇ ಬಾರಿಗೆ ದೃಢೀಕರಣದೊಂದಿಗೆ ಪ್ರತಿಕ್ರಿಯಿಸಿತು. msg_id. ಆದರೆ ಏನಾದರೂ ತಪ್ಪಾದಲ್ಲಿ ಅವನು ಈ ಪ್ಯಾಕ್ ಅನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ತಿರಸ್ಕರಿಸುತ್ತಾನೆ.

ಮತ್ತು ಈ ಹಂತದಲ್ಲಿ ತಾಂತ್ರಿಕವಲ್ಲದ ಪರಿಗಣನೆಗಳು ಕಾರ್ಯರೂಪಕ್ಕೆ ಬರುತ್ತವೆ. ಅನುಭವದಿಂದ, ನಾವು ಅನೇಕ ಊರುಗೋಲುಗಳನ್ನು ನೋಡಿದ್ದೇವೆ ಮತ್ತು ಹೆಚ್ಚುವರಿಯಾಗಿ, ನಾವು ಈಗ ಕೆಟ್ಟ ಸಲಹೆ ಮತ್ತು ವಾಸ್ತುಶಿಲ್ಪದ ಹೆಚ್ಚಿನ ಉದಾಹರಣೆಗಳನ್ನು ನೋಡುತ್ತೇವೆ - ಅಂತಹ ಪರಿಸ್ಥಿತಿಗಳಲ್ಲಿ, ಅಂತಹ ನಿರ್ಧಾರಗಳನ್ನು ನಂಬುವುದು ಮತ್ತು ತೆಗೆದುಕೊಳ್ಳುವುದು ಯೋಗ್ಯವಾಗಿದೆಯೇ? ಪ್ರಶ್ನೆಯು ವಾಕ್ಚಾತುರ್ಯವಾಗಿದೆ (ಸಹಜವಾಗಿ ಅಲ್ಲ).

ನಾವು ಏನು ಮಾತನಾಡುತ್ತಿದ್ದೇವೆ? "ಸಂದೇಶಗಳ ಕುರಿತು ಮಾದಕವಸ್ತು ಸಂದೇಶಗಳು" ಎಂಬ ವಿಷಯದ ಕುರಿತು ನೀವು ಇನ್ನೂ "ನೀವು ಮೂರ್ಖರು, ನಮ್ಮ ಅದ್ಭುತ ಯೋಜನೆಯನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲಾಗಿಲ್ಲ!" ನಂತಹ ಆಕ್ಷೇಪಣೆಗಳೊಂದಿಗೆ ನೀವು ಊಹಿಸಬಹುದು. (ಆದ್ದರಿಂದ ಸಾಮಾನ್ಯ ಜನರು ಮಾಡಬೇಕಾದಂತೆ ಮೊದಲು ದಸ್ತಾವೇಜನ್ನು ಬರೆಯಿರಿ, ತರ್ಕಬದ್ಧತೆ ಮತ್ತು ಪ್ಯಾಕೆಟ್ ವಿನಿಮಯದ ಉದಾಹರಣೆಗಳೊಂದಿಗೆ, ನಂತರ ನಾವು ಮಾತನಾಡುತ್ತೇವೆ), ನಂತರ ಸಮಯಗಳು / ಸಮಯ ಮೀರುವುದು ಸಂಪೂರ್ಣವಾಗಿ ಪ್ರಾಯೋಗಿಕ ಮತ್ತು ನಿರ್ದಿಷ್ಟ ಪ್ರಶ್ನೆಯಾಗಿದೆ, ಇಲ್ಲಿ ಎಲ್ಲವೂ ಬಹಳ ಹಿಂದಿನಿಂದಲೂ ತಿಳಿದಿದೆ. ಸಮಯ ಮೀರುವಿಕೆಯ ಬಗ್ಗೆ ದಸ್ತಾವೇಜನ್ನು ನಮಗೆ ಏನು ಹೇಳುತ್ತದೆ?

RPC ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಕ್ಲೈಂಟ್‌ನಿಂದ (ಸಾಮಾನ್ಯವಾಗಿ, RPC ಪ್ರಶ್ನೆ) ಸಂದೇಶದ ಸ್ವೀಕೃತಿಯನ್ನು ಸರ್ವರ್ ಸಾಮಾನ್ಯವಾಗಿ ಅಂಗೀಕರಿಸುತ್ತದೆ. ಪ್ರತಿಕ್ರಿಯೆಯು ಬಹಳ ಸಮಯದಿಂದ ಬರುತ್ತಿದ್ದರೆ, ಸರ್ವರ್ ಮೊದಲು ರಸೀದಿ ಸ್ವೀಕೃತಿಯನ್ನು ಕಳುಹಿಸಬಹುದು ಮತ್ತು ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ, RPC ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಸ್ವತಃ ಕಳುಹಿಸಬಹುದು.

ಕ್ಲೈಂಟ್ ಸಾಮಾನ್ಯವಾಗಿ ಸರ್ವರ್‌ನಿಂದ ಸಂದೇಶದ ಸ್ವೀಕೃತಿಯನ್ನು ಅಂಗೀಕರಿಸುತ್ತದೆ (ಸಾಮಾನ್ಯವಾಗಿ, RPC ಪ್ರತಿಕ್ರಿಯೆ) ಮುಂದಿನ RPC ಪ್ರಶ್ನೆಗೆ ಸ್ವೀಕೃತಿಯನ್ನು ಸೇರಿಸುವ ಮೂಲಕ ಅದನ್ನು ತಡವಾಗಿ ರವಾನಿಸದಿದ್ದರೆ (ಅದು ರಶೀದಿಯ ನಂತರ 60-120 ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಉತ್ಪತ್ತಿಯಾಗಿದ್ದರೆ, ಹೇಳಬಹುದು. ಸರ್ವರ್‌ನಿಂದ ಸಂದೇಶ). ಆದಾಗ್ಯೂ, ದೀರ್ಘಕಾಲದವರೆಗೆ ಸರ್ವರ್‌ಗೆ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಯಾವುದೇ ಕಾರಣವಿಲ್ಲದಿದ್ದರೆ ಅಥವಾ ಸರ್ವರ್‌ನಿಂದ ಹೆಚ್ಚಿನ ಸಂಖ್ಯೆಯ ಅಂಗೀಕರಿಸದ ಸಂದೇಶಗಳಿದ್ದರೆ (ಸೇ, 16 ಕ್ಕಿಂತ ಹೆಚ್ಚು), ಕ್ಲೈಂಟ್ ಅದ್ವಿತೀಯ ಸ್ವೀಕೃತಿಯನ್ನು ರವಾನಿಸುತ್ತದೆ.

... ನಾನು ಭಾಷಾಂತರಿಸುತ್ತೇನೆ: ನಮಗೆ ಅದು ಎಷ್ಟು ಮತ್ತು ಹೇಗೆ ಬೇಕು ಎಂದು ನಮಗೆ ತಿಳಿದಿಲ್ಲ, ಆದ್ದರಿಂದ ಅದು ಹೀಗಿರಲಿ ಎಂದು ಭಾವಿಸೋಣ.

ಮತ್ತು ಪಿಂಗ್ ಬಗ್ಗೆ:

ಪಿಂಗ್ ಸಂದೇಶಗಳು (PING/PONG)

ping#7abe77ec ping_id:long = Pong;

ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ಅದೇ ಸಂಪರ್ಕಕ್ಕೆ ಹಿಂತಿರುಗಿಸಲಾಗುತ್ತದೆ:

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

ಈ ಸಂದೇಶಗಳಿಗೆ ಸ್ವೀಕೃತಿಗಳ ಅಗತ್ಯವಿಲ್ಲ. ಪಾಂಗ್ ಅನ್ನು ಪಿಂಗ್‌ಗೆ ಪ್ರತಿಕ್ರಿಯೆಯಾಗಿ ಮಾತ್ರ ರವಾನಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಪಿಂಗ್ ಅನ್ನು ಎರಡೂ ಕಡೆಯಿಂದ ಪ್ರಾರಂಭಿಸಬಹುದು.

ಮುಂದೂಡಲ್ಪಟ್ಟ ಸಂಪರ್ಕ ಮುಚ್ಚುವಿಕೆ + PING

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

ಪಿಂಗ್ ನಂತಹ ಕೆಲಸ ಮಾಡುತ್ತದೆ. ಹೆಚ್ಚುವರಿಯಾಗಿ, ಇದನ್ನು ಸ್ವೀಕರಿಸಿದ ನಂತರ, ಸರ್ವರ್ ಟೈಮರ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ, ಅದು ಹಿಂದಿನ ಎಲ್ಲಾ ಟೈಮರ್‌ಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಮರುಹೊಂದಿಸುವ ಅದೇ ಪ್ರಕಾರದ ಹೊಸ ಸಂದೇಶವನ್ನು ಸ್ವೀಕರಿಸದ ಹೊರತು ಪ್ರಸ್ತುತ ಸಂಪರ್ಕವನ್ನು disconnect_delay ಸೆಕೆಂಡುಗಳ ನಂತರ ಮುಚ್ಚುತ್ತದೆ. ಕ್ಲೈಂಟ್ ಪ್ರತಿ 60 ಸೆಕೆಂಡುಗಳಿಗೊಮ್ಮೆ ಈ ಪಿಂಗ್‌ಗಳನ್ನು ಕಳುಹಿಸಿದರೆ, ಉದಾಹರಣೆಗೆ, ಅದು 75 ಸೆಕೆಂಡುಗಳಿಗೆ ಸಮಾನವಾದ disconnect_delay ಅನ್ನು ಹೊಂದಿಸಬಹುದು.

ನೀನು ಹುಚ್ಚನಾ?! 60 ಸೆಕೆಂಡುಗಳಲ್ಲಿ, ರೈಲು ನಿಲ್ದಾಣವನ್ನು ಪ್ರವೇಶಿಸುತ್ತದೆ, ಇಳಿಯುತ್ತದೆ ಮತ್ತು ಪ್ರಯಾಣಿಕರನ್ನು ಕರೆದೊಯ್ಯುತ್ತದೆ ಮತ್ತು ಮತ್ತೆ ಸುರಂಗದಲ್ಲಿ ಸಂಪರ್ಕವನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತದೆ. 120 ಸೆಕೆಂಡುಗಳಲ್ಲಿ, ನೀವು ಅದನ್ನು ಕೇಳುತ್ತಿರುವಾಗ, ಅದು ಇನ್ನೊಂದಕ್ಕೆ ಬರುತ್ತದೆ ಮತ್ತು ಸಂಪರ್ಕವು ಹೆಚ್ಚಾಗಿ ಮುರಿದುಹೋಗುತ್ತದೆ. ಸರಿ, ಕಾಲುಗಳು ಎಲ್ಲಿಂದ ಬರುತ್ತಿವೆ ಎಂಬುದು ಸ್ಪಷ್ಟವಾಗಿದೆ - "ನಾನು ರಿಂಗಿಂಗ್ ಅನ್ನು ಕೇಳಿದೆ, ಆದರೆ ಅದು ಎಲ್ಲಿದೆ ಎಂದು ನನಗೆ ತಿಳಿದಿಲ್ಲ", ಸಂವಾದಾತ್ಮಕ ಕೆಲಸಕ್ಕಾಗಿ ಉದ್ದೇಶಿಸಲಾದ Nagl ನ ಅಲ್ಗಾರಿದಮ್ ಮತ್ತು TCP_NODELAY ಆಯ್ಕೆ ಇದೆ. ಆದರೆ, ಕ್ಷಮಿಸಿ, ಅದರ ಡೀಫಾಲ್ಟ್ ಮೌಲ್ಯವನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ - 200 ಮಿಲಿಸೆಕೆಂಡುಗಳು ನೀವು ನಿಜವಾಗಿಯೂ ಇದೇ ರೀತಿಯದನ್ನು ಚಿತ್ರಿಸಲು ಮತ್ತು ಸಂಭವನೀಯ ಒಂದೆರಡು ಪ್ಯಾಕೆಟ್‌ಗಳಲ್ಲಿ ಉಳಿಸಲು ಬಯಸಿದರೆ, ನಂತರ ಅದನ್ನು 5 ಸೆಕೆಂಡುಗಳ ಕಾಲ ನಿಲ್ಲಿಸಿ ಅಥವಾ "ಬಳಕೆದಾರರು ಟೈಪ್ ಮಾಡುತ್ತಿದ್ದಾರೆ..." ಸಂದೇಶದ ಸಮಯ ಮೀರಿದೆ. ಆದರೆ ಇನ್ನು ಇಲ್ಲ.

ಮತ್ತು ಅಂತಿಮವಾಗಿ, ಪಿಂಗ್ಸ್. ಅಂದರೆ, TCP ಸಂಪರ್ಕದ ಜೀವಂತಿಕೆಯನ್ನು ಪರಿಶೀಲಿಸುವುದು. ಇದು ತಮಾಷೆಯಾಗಿದೆ, ಆದರೆ ಸುಮಾರು 10 ವರ್ಷಗಳ ಹಿಂದೆ ನಾನು ನಮ್ಮ ಅಧ್ಯಾಪಕರ ಡಾರ್ಮ್‌ನ ಮೆಸೆಂಜರ್ ಬಗ್ಗೆ ವಿಮರ್ಶಾತ್ಮಕ ಪಠ್ಯವನ್ನು ಬರೆದಿದ್ದೇನೆ - ಅಲ್ಲಿನ ಲೇಖಕರು ಕ್ಲೈಂಟ್‌ನಿಂದ ಸರ್ವರ್ ಅನ್ನು ಪಿಂಗ್ ಮಾಡಿದ್ದಾರೆ ಮತ್ತು ಪ್ರತಿಯಾಗಿ ಅಲ್ಲ. ಆದರೆ 3 ನೇ ವರ್ಷದ ವಿದ್ಯಾರ್ಥಿಗಳು ಒಂದು ವಿಷಯ, ಮತ್ತು ಅಂತರರಾಷ್ಟ್ರೀಯ ಕಚೇರಿ ಇನ್ನೊಂದು, ಸರಿ?..

ಮೊದಲಿಗೆ, ಸ್ವಲ್ಪ ಶೈಕ್ಷಣಿಕ ಕಾರ್ಯಕ್ರಮ. ಪ್ಯಾಕೆಟ್ ವಿನಿಮಯದ ಅನುಪಸ್ಥಿತಿಯಲ್ಲಿ TCP ಸಂಪರ್ಕವು ವಾರಗಳವರೆಗೆ ಬದುಕಬಲ್ಲದು. ಉದ್ದೇಶವನ್ನು ಅವಲಂಬಿಸಿ ಇದು ಒಳ್ಳೆಯದು ಮತ್ತು ಕೆಟ್ಟದು. ನೀವು ಸರ್ವರ್‌ಗೆ SSH ಸಂಪರ್ಕವನ್ನು ತೆರೆದಿದ್ದರೆ ಒಳ್ಳೆಯದು, ನೀವು ಕಂಪ್ಯೂಟರ್‌ನಿಂದ ಎದ್ದು, ರೂಟರ್ ಅನ್ನು ರೀಬೂಟ್ ಮಾಡಿ, ನಿಮ್ಮ ಸ್ಥಳಕ್ಕೆ ಹಿಂತಿರುಗಿ - ಈ ಸರ್ವರ್ ಮೂಲಕ ಸೆಷನ್ ಹರಿದಿಲ್ಲ (ನೀವು ಏನನ್ನೂ ಟೈಪ್ ಮಾಡಿಲ್ಲ, ಯಾವುದೇ ಪ್ಯಾಕೆಟ್‌ಗಳಿಲ್ಲ) , ಇದು ಅನುಕೂಲಕರವಾಗಿದೆ. ಸರ್ವರ್‌ನಲ್ಲಿ ಸಾವಿರಾರು ಕ್ಲೈಂಟ್‌ಗಳಿದ್ದರೆ ಅದು ಕೆಟ್ಟದಾಗಿದೆ, ಪ್ರತಿಯೊಬ್ಬರೂ ಸಂಪನ್ಮೂಲಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತಾರೆ (ಹಲೋ, ಪೋಸ್ಟ್‌ಗ್ರೆಸ್!), ಮತ್ತು ಕ್ಲೈಂಟ್‌ನ ಹೋಸ್ಟ್ ಬಹಳ ಹಿಂದೆಯೇ ರೀಬೂಟ್ ಮಾಡಿರಬಹುದು - ಆದರೆ ಅದರ ಬಗ್ಗೆ ನಮಗೆ ತಿಳಿದಿಲ್ಲ.

ಚಾಟ್/IM ವ್ಯವಸ್ಥೆಗಳು ಒಂದು ಹೆಚ್ಚುವರಿ ಕಾರಣಕ್ಕಾಗಿ ಎರಡನೇ ಪ್ರಕರಣಕ್ಕೆ ಸೇರುತ್ತವೆ - ಆನ್‌ಲೈನ್ ಸ್ಥಿತಿಗಳು. ಬಳಕೆದಾರನು "ಬಿದ್ದುಹೋದರೆ", ನೀವು ಈ ಬಗ್ಗೆ ಅವರ ಸಂವಾದಕರಿಗೆ ತಿಳಿಸಬೇಕು. ಇಲ್ಲದಿದ್ದರೆ, ಜಬ್ಬರ್‌ನ ರಚನೆಕಾರರು ಮಾಡಿದ (ಮತ್ತು 20 ವರ್ಷಗಳಿಂದ ಸರಿಪಡಿಸಿದ) ತಪ್ಪಿಗೆ ನೀವು ಕೊನೆಗೊಳ್ಳುವಿರಿ - ಬಳಕೆದಾರರು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿದ್ದಾರೆ, ಆದರೆ ಅವರು ಆನ್‌ಲೈನ್‌ನಲ್ಲಿದ್ದಾರೆ ಎಂದು ನಂಬಿ ಅವರಿಗೆ ಸಂದೇಶಗಳನ್ನು ಬರೆಯುವುದನ್ನು ಮುಂದುವರಿಸುತ್ತಾರೆ (ಅವುಗಳು ಇವುಗಳಲ್ಲಿ ಸಂಪೂರ್ಣವಾಗಿ ಕಳೆದುಹೋಗಿವೆ. ಸಂಪರ್ಕ ಕಡಿತವನ್ನು ಕಂಡುಹಿಡಿಯುವ ಕೆಲವು ನಿಮಿಷಗಳ ಮೊದಲು). ಇಲ್ಲ, TCP_KEEPALIVE ಆಯ್ಕೆಯು, TCP ಟೈಮರ್‌ಗಳು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ ಎಂಬುದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳದ ಅನೇಕ ಜನರು ಯಾದೃಚ್ಛಿಕವಾಗಿ ಎಸೆಯುತ್ತಾರೆ (ಹತ್ತಾರು ಸೆಕೆಂಡುಗಳಂತೆ ವೈಲ್ಡ್ ಮೌಲ್ಯಗಳನ್ನು ಹೊಂದಿಸುವ ಮೂಲಕ), ಇಲ್ಲಿ ಸಹಾಯ ಮಾಡುವುದಿಲ್ಲ - ನೀವು OS ಕರ್ನಲ್ ಮಾತ್ರವಲ್ಲ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಬೇಕು ಬಳಕೆದಾರರ ಯಂತ್ರವು ಜೀವಂತವಾಗಿದೆ, ಆದರೆ ಸಾಮಾನ್ಯವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಪ್ರತಿಕ್ರಿಯಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ, ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್ ಸ್ವತಃ (ಇದು ಫ್ರೀಜ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ ಎಂದು ನೀವು ಭಾವಿಸುತ್ತೀರಾ? ಉಬುಂಟು 18.04 ನಲ್ಲಿನ ಟೆಲಿಗ್ರಾಮ್ ಡೆಸ್ಕ್‌ಟಾಪ್ ನನಗೆ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ಸ್ಥಗಿತಗೊಂಡಿದೆ).

ಅದಕ್ಕಾಗಿಯೇ ನೀವು ಪಿಂಗ್ ಮಾಡಬೇಕು ಸರ್ವರ್ ಕ್ಲೈಂಟ್, ಮತ್ತು ಪ್ರತಿಯಾಗಿ ಅಲ್ಲ - ಕ್ಲೈಂಟ್ ಇದನ್ನು ಮಾಡಿದರೆ, ಸಂಪರ್ಕವು ಮುರಿದುಹೋದರೆ, ಪಿಂಗ್ ಅನ್ನು ತಲುಪಿಸಲಾಗುವುದಿಲ್ಲ, ಗುರಿಯನ್ನು ಸಾಧಿಸಲಾಗುವುದಿಲ್ಲ.

ಟೆಲಿಗ್ರಾಮ್‌ನಲ್ಲಿ ನಾವು ಏನು ನೋಡುತ್ತೇವೆ? ಇದು ನಿಖರವಾಗಿ ವಿರುದ್ಧವಾಗಿದೆ! ಸರಿ, ಅಂದರೆ. ಔಪಚಾರಿಕವಾಗಿ, ಎರಡೂ ಕಡೆಯವರು ಪರಸ್ಪರ ಪಿಂಗ್ ಮಾಡಬಹುದು. ಪ್ರಾಯೋಗಿಕವಾಗಿ, ಗ್ರಾಹಕರು ಊರುಗೋಲನ್ನು ಬಳಸುತ್ತಾರೆ ping_delay_disconnect, ಇದು ಸರ್ವರ್‌ನಲ್ಲಿ ಟೈಮರ್ ಅನ್ನು ಹೊಂದಿಸುತ್ತದೆ. ಸರಿ, ನನ್ನನ್ನು ಕ್ಷಮಿಸಿ, ಕ್ಲೈಂಟ್ ಪಿಂಗ್ ಇಲ್ಲದೆ ಎಷ್ಟು ಕಾಲ ಅಲ್ಲಿ ವಾಸಿಸಲು ಬಯಸುತ್ತಾನೆ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸಲು ಇದು ಅಲ್ಲ. ಸರ್ವರ್, ಅದರ ಲೋಡ್ ಅನ್ನು ಆಧರಿಸಿ, ಚೆನ್ನಾಗಿ ತಿಳಿದಿದೆ. ಆದರೆ, ಸಹಜವಾಗಿ, ನೀವು ಸಂಪನ್ಮೂಲಗಳನ್ನು ಮನಸ್ಸಿಲ್ಲದಿದ್ದರೆ, ನೀವು ನಿಮ್ಮ ಸ್ವಂತ ದುಷ್ಟ ಪಿನೋಚ್ಚಿಯೋ ಆಗುತ್ತೀರಿ, ಮತ್ತು ಊರುಗೋಲು ಮಾಡುತ್ತದೆ ...

ಅದನ್ನು ಹೇಗೆ ವಿನ್ಯಾಸಗೊಳಿಸಬೇಕಿತ್ತು?

ಟೆಲಿಗ್ರಾಮ್/VKontakte ತಂಡವು ಸಾರಿಗೆ ಕ್ಷೇತ್ರದಲ್ಲಿ (ಮತ್ತು ಕಡಿಮೆ) ಮಟ್ಟದ ಕಂಪ್ಯೂಟರ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಮತ್ತು ಸಂಬಂಧಿತ ವಿಷಯಗಳಲ್ಲಿ ಅವರ ಕಡಿಮೆ ಅರ್ಹತೆಗಳಲ್ಲಿ ಹೆಚ್ಚು ಸಮರ್ಥವಾಗಿಲ್ಲ ಎಂದು ಮೇಲಿನ ಸಂಗತಿಗಳು ಸ್ಪಷ್ಟವಾಗಿ ಸೂಚಿಸುತ್ತವೆ ಎಂದು ನಾನು ನಂಬುತ್ತೇನೆ.

ಅದು ಏಕೆ ತುಂಬಾ ಜಟಿಲವಾಗಿದೆ, ಮತ್ತು ಟೆಲಿಗ್ರಾಮ್ ವಾಸ್ತುಶಿಲ್ಪಿಗಳು ಆಕ್ಷೇಪಿಸಲು ಹೇಗೆ ಪ್ರಯತ್ನಿಸಬಹುದು? ಅವರು TCP ಸಂಪರ್ಕವನ್ನು ಉಳಿದುಕೊಂಡಿರುವ ಸೆಶನ್ ಅನ್ನು ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದಾರೆ ಎಂಬ ಅಂಶವು ಮುರಿದುಹೋಗುತ್ತದೆ, ಅಂದರೆ, ಈಗ ಏನು ವಿತರಿಸಲಾಗಿಲ್ಲ, ನಾವು ನಂತರ ತಲುಪಿಸುತ್ತೇವೆ. ಅವರು ಬಹುಶಃ ಯುಡಿಪಿ ಸಾರಿಗೆಯನ್ನು ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದರು, ಆದರೆ ಅವರು ತೊಂದರೆಗಳನ್ನು ಎದುರಿಸಿದರು ಮತ್ತು ಅದನ್ನು ತ್ಯಜಿಸಿದರು (ಅದಕ್ಕಾಗಿಯೇ ದಸ್ತಾವೇಜನ್ನು ಖಾಲಿಯಾಗಿದೆ - ಹೆಮ್ಮೆಪಡಲು ಏನೂ ಇಲ್ಲ). ಆದರೆ ಸಾಮಾನ್ಯವಾಗಿ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಮತ್ತು ನಿರ್ದಿಷ್ಟವಾಗಿ ಟಿಸಿಪಿ ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ನೀವು ಅದನ್ನು ಎಲ್ಲಿ ಅವಲಂಬಿಸಬಹುದು ಮತ್ತು ಅದನ್ನು ನೀವೇ ಎಲ್ಲಿ ಮಾಡಬೇಕು (ಮತ್ತು ಹೇಗೆ) ಮತ್ತು ಇದನ್ನು ಕ್ರಿಪ್ಟೋಗ್ರಫಿಯೊಂದಿಗೆ ಸಂಯೋಜಿಸುವ ಪ್ರಯತ್ನ "ಎರಡು ಪಕ್ಷಿಗಳೊಂದಿಗೆ" ಎಂಬ ತಿಳುವಳಿಕೆ ಕೊರತೆಯಿಂದಾಗಿ ಒಂದು ಕಲ್ಲು”, ಇದು ಫಲಿತಾಂಶವಾಗಿದೆ.

ಅದು ಹೇಗೆ ಅಗತ್ಯವಾಗಿತ್ತು? ಎಂಬ ಅಂಶವನ್ನು ಆಧರಿಸಿ msg_id ಮರುಪಂದ್ಯದ ದಾಳಿಯನ್ನು ತಡೆಗಟ್ಟಲು ಕ್ರಿಪ್ಟೋಗ್ರಾಫಿಕ್ ದೃಷ್ಟಿಕೋನದಿಂದ ಸಮಯಸ್ಟ್ಯಾಂಪ್ ಅವಶ್ಯಕವಾಗಿದೆ, ಅದಕ್ಕೆ ಅನನ್ಯ ಗುರುತಿಸುವಿಕೆಯ ಕಾರ್ಯವನ್ನು ಲಗತ್ತಿಸುವುದು ತಪ್ಪು. ಆದ್ದರಿಂದ, ಪ್ರಸ್ತುತ ಆರ್ಕಿಟೆಕ್ಚರ್ ಅನ್ನು ಮೂಲಭೂತವಾಗಿ ಬದಲಾಯಿಸದೆಯೇ (ಅಪ್‌ಡೇಟ್‌ಗಳ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ರಚಿಸಿದಾಗ, ಈ ಪೋಸ್ಟ್‌ಗಳ ಸರಣಿಯ ಮತ್ತೊಂದು ಭಾಗಕ್ಕೆ ಇದು ಉನ್ನತ ಮಟ್ಟದ API ವಿಷಯವಾಗಿದೆ), ಒಬ್ಬರು ಹೀಗೆ ಮಾಡಬೇಕಾಗುತ್ತದೆ:

  1. ಕ್ಲೈಂಟ್‌ಗೆ TCP ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿರುವ ಸರ್ವರ್ ಜವಾಬ್ದಾರಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ - ಅದು ಸಾಕೆಟ್‌ನಿಂದ ಓದಿದ್ದರೆ, ದಯವಿಟ್ಟು ದೋಷವನ್ನು ಒಪ್ಪಿಕೊಳ್ಳಿ, ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಿ ಅಥವಾ ಹಿಂತಿರುಗಿಸಿ, ಯಾವುದೇ ನಷ್ಟವಿಲ್ಲ. ನಂತರ ದೃಢೀಕರಣವು ಐಡಿಗಳ ವೆಕ್ಟರ್ ಅಲ್ಲ, ಆದರೆ ಸರಳವಾಗಿ "ಕೊನೆಯದಾಗಿ ಸ್ವೀಕರಿಸಿದ seq_no" - ಕೇವಲ ಒಂದು ಸಂಖ್ಯೆ, TCP ಯಲ್ಲಿರುವಂತೆ (ಎರಡು ಸಂಖ್ಯೆಗಳು - ನಿಮ್ಮ seq ಮತ್ತು ದೃಢಪಡಿಸಿದ ಒಂದು). ನಾವು ಯಾವಾಗಲೂ ಅಧಿವೇಶನದೊಳಗೆ ಇರುತ್ತೇವೆ, ಅಲ್ಲವೇ?
  2. ಮರುಪಂದ್ಯದ ದಾಳಿಯನ್ನು ತಡೆಗಟ್ಟುವ ಸಮಯ ಸ್ಟ್ಯಾಂಪ್ ಪ್ರತ್ಯೇಕ ಕ್ಷೇತ್ರವಾಗಿ ಮಾರ್ಪಡುತ್ತದೆ. ಇದನ್ನು ಪರಿಶೀಲಿಸಲಾಗಿದೆ, ಆದರೆ ಬೇರೆ ಯಾವುದಕ್ಕೂ ಪರಿಣಾಮ ಬೀರುವುದಿಲ್ಲ. ಸಾಕಷ್ಟು ಮತ್ತು uint32 - ನಮ್ಮ ಉಪ್ಪು ಕನಿಷ್ಠ ಅರ್ಧ ದಿನಕ್ಕೊಮ್ಮೆ ಬದಲಾದರೆ, ನಾವು 16 ಬಿಟ್‌ಗಳನ್ನು ಪ್ರಸ್ತುತ ಸಮಯದ ಪೂರ್ಣಾಂಕದ ಭಾಗದ ಕಡಿಮೆ-ಆರ್ಡರ್ ಬಿಟ್‌ಗಳಿಗೆ ನಿಯೋಜಿಸಬಹುದು, ಉಳಿದವು - ಸೆಕೆಂಡಿನ ಭಾಗಶಃ ಭಾಗಕ್ಕೆ (ಈಗ ಹಾಗೆ).
  3. ತೆಗೆದುಹಾಕಲಾಗಿದೆ msg_id ಎಲ್ಲಾ - ಬ್ಯಾಕೆಂಡ್‌ಗಳಲ್ಲಿ ವಿನಂತಿಗಳನ್ನು ಪ್ರತ್ಯೇಕಿಸುವ ದೃಷ್ಟಿಕೋನದಿಂದ, ಮೊದಲನೆಯದಾಗಿ, ಕ್ಲೈಂಟ್ ಐಡಿ ಮತ್ತು ಎರಡನೆಯದಾಗಿ, ಸೆಷನ್ ಐಡಿ, ಅವುಗಳನ್ನು ಒಟ್ಟುಗೂಡಿಸಿ. ಅಂತೆಯೇ, ವಿನಂತಿಯ ಗುರುತಿಸುವಿಕೆಯಾಗಿ ಒಂದೇ ಒಂದು ವಿಷಯ ಸಾಕು seq_no.

ಇದು ಅತ್ಯಂತ ಯಶಸ್ವಿ ಆಯ್ಕೆಯೂ ಅಲ್ಲ; ಸಂಪೂರ್ಣ ಯಾದೃಚ್ಛಿಕವು ಗುರುತಿಸುವಿಕೆಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ - ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುವಾಗ ಇದನ್ನು ಈಗಾಗಲೇ ಉನ್ನತ ಮಟ್ಟದ API ನಲ್ಲಿ ಮಾಡಲಾಗುತ್ತದೆ. ಆರ್ಕಿಟೆಕ್ಚರ್ ಅನ್ನು ಸಾಪೇಕ್ಷದಿಂದ ಸಂಪೂರ್ಣಕ್ಕೆ ಸಂಪೂರ್ಣವಾಗಿ ರೀಮೇಕ್ ಮಾಡುವುದು ಉತ್ತಮ, ಆದರೆ ಇದು ಮತ್ತೊಂದು ಭಾಗಕ್ಕೆ ವಿಷಯವಾಗಿದೆ, ಈ ಪೋಸ್ಟ್ ಅಲ್ಲ.

API?

ತಾ-ದಾಮ್! ಆದ್ದರಿಂದ, ನೋವು ಮತ್ತು ಊರುಗೋಲುಗಳಿಂದ ತುಂಬಿದ ಹಾದಿಯಲ್ಲಿ ಹೋರಾಡಿದ ನಂತರ, ನಾವು ಅಂತಿಮವಾಗಿ ಸರ್ವರ್‌ಗೆ ಯಾವುದೇ ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸಲು ಮತ್ತು ಅವುಗಳಿಗೆ ಯಾವುದೇ ಉತ್ತರಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಮತ್ತು ಸರ್ವರ್‌ನಿಂದ ನವೀಕರಣಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಸಾಧ್ಯವಾಯಿತು (ವಿನಂತಿಗೆ ಪ್ರತಿಕ್ರಿಯೆಯಾಗಿ ಅಲ್ಲ, ಆದರೆ ಅದು ಸ್ವತಃ ಯಾರಿಗಾದರೂ ಅದು ಸ್ಪಷ್ಟವಾಗಿದ್ದರೆ ಪುಶ್‌ನಂತೆ ನಮಗೆ ಕಳುಹಿಸುತ್ತದೆ).

ಗಮನ, ಈಗ ಲೇಖನದಲ್ಲಿ ಪರ್ಲ್‌ನಲ್ಲಿ ಒಂದೇ ಉದಾಹರಣೆ ಇರುತ್ತದೆ! (ಸಿಂಟ್ಯಾಕ್ಸ್‌ನ ಪರಿಚಯವಿಲ್ಲದವರಿಗೆ, ಬ್ಲೆಸ್‌ನ ಮೊದಲ ವಾದವು ವಸ್ತುವಿನ ಡೇಟಾ ರಚನೆಯಾಗಿದೆ, ಎರಡನೆಯದು ಅದರ ವರ್ಗವಾಗಿದೆ):

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

ಹೌದು, ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಸ್ಪಾಯ್ಲರ್ ಅಲ್ಲ - ನೀವು ಅದನ್ನು ಇನ್ನೂ ಓದದಿದ್ದರೆ, ಮುಂದುವರಿಯಿರಿ ಮತ್ತು ಅದನ್ನು ಮಾಡಿ!

ಓಹ್, ವೈ~~... ಇದು ಹೇಗಿದೆ? ಯಾವುದೋ ಬಹಳ ಪರಿಚಿತವಾಗಿದೆ... ಬಹುಶಃ ಇದು JSON ನಲ್ಲಿನ ವಿಶಿಷ್ಟವಾದ ವೆಬ್ API ಯ ಡೇಟಾ ರಚನೆಯಾಗಿರಬಹುದು, ಹೊರತುಪಡಿಸಿ ತರಗತಿಗಳು ಆಬ್ಜೆಕ್ಟ್‌ಗಳಿಗೆ ಲಗತ್ತಿಸಲಾಗಿದೆಯೇ?..

ಆದ್ದರಿಂದ ಇದು ಹೇಗೆ ತಿರುಗುತ್ತದೆ ... ಅದು ಏನು, ಒಡನಾಡಿಗಳು? ಕೇವಲ ಪ್ರಾರಂಭವಾಗುತ್ತಿದೆ?.. HTTPS ಮೂಲಕ JSON ಸರಳವಾಗಿರುವುದಿಲ್ಲವೇ?! ವಿನಿಮಯವಾಗಿ ನಾವು ಏನು ಪಡೆದುಕೊಂಡಿದ್ದೇವೆ? ಪ್ರಯತ್ನವು ಯೋಗ್ಯವಾಗಿದೆಯೇ?

TL+MTProto ನಮಗೆ ಏನು ನೀಡಿದೆ ಮತ್ತು ಯಾವ ಪರ್ಯಾಯಗಳು ಸಾಧ್ಯ ಎಂಬುದನ್ನು ಮೌಲ್ಯಮಾಪನ ಮಾಡೋಣ. ಸರಿ, ವಿನಂತಿ-ಪ್ರತಿಕ್ರಿಯೆ ಮಾದರಿಯ ಮೇಲೆ ಕೇಂದ್ರೀಕರಿಸುವ HTTP, ಕೆಟ್ಟ ಫಿಟ್ ಆಗಿದೆ, ಆದರೆ ಕನಿಷ್ಠ TLS ಮೇಲೆ ಏನಾದರೂ ಇದೆಯೇ?

ಕಾಂಪ್ಯಾಕ್ಟ್ ಧಾರಾವಾಹಿ. JSON ನಂತೆಯೇ ಈ ಡೇಟಾ ರಚನೆಯನ್ನು ನೋಡಿದಾಗ, ಅದರ ಬೈನರಿ ಆವೃತ್ತಿಗಳಿವೆ ಎಂದು ನನಗೆ ನೆನಪಿದೆ. MsgPack ಅನ್ನು ಸಾಕಷ್ಟು ವಿಸ್ತರಿಸಲಾಗುವುದಿಲ್ಲ ಎಂದು ಗುರುತಿಸೋಣ, ಆದರೆ, ಉದಾಹರಣೆಗೆ, CBOR - ಮೂಲಕ, ಒಂದು ಮಾನದಂಡವನ್ನು ವಿವರಿಸಲಾಗಿದೆ RFC 7049. ಇದು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ ಎಂಬ ಅಂಶಕ್ಕೆ ಇದು ಗಮನಾರ್ಹವಾಗಿದೆ ಟ್ಯಾಗ್‌ಗಳು, ವಿಸ್ತರಣೆ ಯಾಂತ್ರಿಕವಾಗಿ, ಮತ್ತು ನಡುವೆ ಈಗಾಗಲೇ ಪ್ರಮಾಣೀಕರಿಸಲಾಗಿದೆ ಲಭ್ಯವಿದೆ:

  • 25 + 256 - ಪುನರಾವರ್ತಿತ ಸಾಲುಗಳನ್ನು ಲೈನ್ ಸಂಖ್ಯೆಗೆ ಉಲ್ಲೇಖದೊಂದಿಗೆ ಬದಲಾಯಿಸುವುದು, ಅಂತಹ ಅಗ್ಗದ ಸಂಕೋಚನ ವಿಧಾನ
  • 26 - ವರ್ಗದ ಹೆಸರು ಮತ್ತು ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳೊಂದಿಗೆ ಸರಣಿ ಪರ್ಲ್ ವಸ್ತು
  • 27 - ಪ್ರಕಾರದ ಹೆಸರು ಮತ್ತು ಕನ್‌ಸ್ಟ್ರಕ್ಟರ್ ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳೊಂದಿಗೆ ಧಾರಾವಾಹಿ ಭಾಷೆ-ಸ್ವತಂತ್ರ ವಸ್ತು

ಸರಿ, ನಾನು TL ಮತ್ತು CBOR ನಲ್ಲಿ ಸ್ಟ್ರಿಂಗ್ ಮತ್ತು ಆಬ್ಜೆಕ್ಟ್ ಪ್ಯಾಕಿಂಗ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ ಅದೇ ಡೇಟಾವನ್ನು ಧಾರಾವಾಹಿ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದೆ. ಫಲಿತಾಂಶವು ಮೆಗಾಬೈಟ್‌ನಿಂದ ಎಲ್ಲೋ CBOR ಪರವಾಗಿ ಬದಲಾಗಲಾರಂಭಿಸಿತು:

cborlen=1039673 tl_len=1095092

ಆದ್ದರಿಂದ, ತೀರ್ಮಾನ: ಹೋಲಿಸಬಹುದಾದ ದಕ್ಷತೆಯೊಂದಿಗೆ ಸಿಂಕ್ರೊನೈಸೇಶನ್ ವೈಫಲ್ಯ ಅಥವಾ ಅಜ್ಞಾತ ಗುರುತಿಸುವಿಕೆಯ ಸಮಸ್ಯೆಗೆ ಒಳಪಡದ ಗಣನೀಯವಾಗಿ ಸರಳವಾದ ಸ್ವರೂಪಗಳಿವೆ.

ವೇಗದ ಸಂಪರ್ಕ ಸ್ಥಾಪನೆ. ಇದರರ್ಥ ಮರುಸಂಪರ್ಕದ ನಂತರ ಶೂನ್ಯ RTT (ಕೀಲಿಯನ್ನು ಈಗಾಗಲೇ ಒಮ್ಮೆ ರಚಿಸಿದಾಗ) - ಮೊದಲ MTProto ಸಂದೇಶದಿಂದ ಅನ್ವಯಿಸುತ್ತದೆ, ಆದರೆ ಕೆಲವು ಮೀಸಲಾತಿಗಳೊಂದಿಗೆ - ಅದೇ ಉಪ್ಪನ್ನು ಹೊಡೆಯಿರಿ, ಸೆಷನ್ ಕೊಳೆತವಾಗಿಲ್ಲ, ಇತ್ಯಾದಿ. ಬದಲಿಗೆ TLS ನಮಗೆ ಏನು ನೀಡುತ್ತದೆ? ವಿಷಯದ ಮೇಲೆ ಉಲ್ಲೇಖ:

TLS, TLS ಸೆಷನ್ ಟಿಕೆಟ್‌ಗಳಲ್ಲಿ PFS ಬಳಸುವಾಗ (RFC 5077) ಕೀಗಳನ್ನು ಮರು-ಸಂಧಾನ ಮಾಡದೆ ಮತ್ತು ಸರ್ವರ್‌ನಲ್ಲಿ ಪ್ರಮುಖ ಮಾಹಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸದೆ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಿದ ಅಧಿವೇಶನವನ್ನು ಪುನರಾರಂಭಿಸಲು. ಮೊದಲ ಸಂಪರ್ಕವನ್ನು ತೆರೆಯುವಾಗ ಮತ್ತು ಕೀಗಳನ್ನು ರಚಿಸುವಾಗ, ಸರ್ವರ್ ಸಂಪರ್ಕ ಸ್ಥಿತಿಯನ್ನು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಅದನ್ನು ಕ್ಲೈಂಟ್‌ಗೆ ರವಾನಿಸುತ್ತದೆ (ಸೆಶನ್ ಟಿಕೆಟ್ ರೂಪದಲ್ಲಿ). ಅದರಂತೆ, ಸಂಪರ್ಕವನ್ನು ಪುನರಾರಂಭಿಸಿದಾಗ, ಕ್ಲೈಂಟ್ ಸೆಷನ್ ಕೀ ಸೇರಿದಂತೆ ಸೆಷನ್ ಟಿಕೆಟ್ ಅನ್ನು ಸರ್ವರ್‌ಗೆ ಕಳುಹಿಸುತ್ತಾನೆ. ಟಿಕೆಟ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕ ಕೀಲಿಯೊಂದಿಗೆ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ (ಸೆಷನ್ ಟಿಕೆಟ್ ಕೀ), ಇದನ್ನು ಸರ್ವರ್‌ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಕ್ಲಸ್ಟರ್ಡ್ ಪರಿಹಾರಗಳಲ್ಲಿ SSL ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವ ಎಲ್ಲಾ ಮುಂಭಾಗದ ಸರ್ವರ್‌ಗಳಲ್ಲಿ ವಿತರಿಸಬೇಕು.[10]. ಹೀಗಾಗಿ, ತಾತ್ಕಾಲಿಕ ಸರ್ವರ್ ಕೀಗಳು ರಾಜಿ ಮಾಡಿಕೊಂಡರೆ ಸೆಷನ್ ಟಿಕೆಟ್‌ನ ಪರಿಚಯವು PFS ಅನ್ನು ಉಲ್ಲಂಘಿಸಬಹುದು, ಉದಾಹರಣೆಗೆ, ಅವುಗಳನ್ನು ದೀರ್ಘಕಾಲದವರೆಗೆ ಸಂಗ್ರಹಿಸಿದಾಗ (OpenSSL, nginx, Apache ಪ್ರೋಗ್ರಾಂನ ಸಂಪೂರ್ಣ ಅವಧಿಗೆ ಪೂರ್ವನಿಯೋಜಿತವಾಗಿ ಅವುಗಳನ್ನು ಸಂಗ್ರಹಿಸುತ್ತದೆ; ಜನಪ್ರಿಯ ಸೈಟ್‌ಗಳು ಬಳಸುತ್ತವೆ ಕೀಲಿಯು ಹಲವಾರು ಗಂಟೆಗಳವರೆಗೆ, ದಿನಗಳವರೆಗೆ).

ಇಲ್ಲಿ RTT ಶೂನ್ಯವಾಗಿಲ್ಲ, ನೀವು ಕನಿಷ್ಟ ClientHello ಮತ್ತು ServerHello ಅನ್ನು ವಿನಿಮಯ ಮಾಡಿಕೊಳ್ಳಬೇಕು, ಅದರ ನಂತರ ಕ್ಲೈಂಟ್ ಮುಗಿದ ಜೊತೆಗೆ ಡೇಟಾವನ್ನು ಕಳುಹಿಸಬಹುದು. ಆದರೆ ಇಲ್ಲಿ ನಾವು ಹೊಸದಾಗಿ ತೆರೆಯಲಾದ ಸಂಪರ್ಕಗಳ ಗುಂಪನ್ನು ಹೊಂದಿರುವ ವೆಬ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ, ಆದರೆ ಸಂದೇಶವಾಹಕ, ಅದರ ಸಂಪರ್ಕವು ಸಾಮಾನ್ಯವಾಗಿ ಒಂದು ಮತ್ತು ಹೆಚ್ಚು ಅಥವಾ ಕಡಿಮೆ ದೀರ್ಘಾವಧಿಯ, ವೆಬ್ ಪುಟಗಳಿಗೆ ತುಲನಾತ್ಮಕವಾಗಿ ಕಡಿಮೆ ವಿನಂತಿಗಳನ್ನು ಹೊಂದಿದೆ - ಎಲ್ಲವೂ ಮಲ್ಟಿಪ್ಲೆಕ್ಸ್ ಆಗಿದೆ ಆಂತರಿಕವಾಗಿ. ಅಂದರೆ, ನಾವು ನಿಜವಾಗಿಯೂ ಕೆಟ್ಟ ಸುರಂಗಮಾರ್ಗ ವಿಭಾಗವನ್ನು ನೋಡದಿದ್ದರೆ ಅದು ಸಾಕಷ್ಟು ಸ್ವೀಕಾರಾರ್ಹವಾಗಿದೆ.

ಇನ್ನೇನಾದರೂ ಮರೆತಿರುವಿರಾ? ಕಾಮೆಂಟ್‌ಗಳಲ್ಲಿ ಬರೆಯಿರಿ.

ಮುಂದುವರೆಯುವುದು!

ಈ ಪೋಸ್ಟ್‌ಗಳ ಸರಣಿಯ ಎರಡನೇ ಭಾಗದಲ್ಲಿ ನಾವು ತಾಂತ್ರಿಕವಲ್ಲ, ಆದರೆ ಸಾಂಸ್ಥಿಕ ಸಮಸ್ಯೆಗಳನ್ನು ಪರಿಗಣಿಸುತ್ತೇವೆ - ವಿಧಾನಗಳು, ಸಿದ್ಧಾಂತ, ಇಂಟರ್ಫೇಸ್, ಬಳಕೆದಾರರ ಬಗೆಗಿನ ವರ್ತನೆ, ಇತ್ಯಾದಿ. ಆದಾಗ್ಯೂ, ಇಲ್ಲಿ ಪ್ರಸ್ತುತಪಡಿಸಲಾದ ತಾಂತ್ರಿಕ ಮಾಹಿತಿಯ ಆಧಾರದ ಮೇಲೆ.

ಮೂರನೇ ಭಾಗವು ತಾಂತ್ರಿಕ ಘಟಕ / ಅಭಿವೃದ್ಧಿ ಅನುಭವವನ್ನು ವಿಶ್ಲೇಷಿಸುವುದನ್ನು ಮುಂದುವರಿಸುತ್ತದೆ. ನೀವು ನಿರ್ದಿಷ್ಟವಾಗಿ ಕಲಿಯುವಿರಿ:

  • ವಿವಿಧ TL ಪ್ರಕಾರಗಳೊಂದಿಗೆ ಕೋಲಾಹಲದ ಮುಂದುವರಿಕೆ
  • ಚಾನಲ್‌ಗಳು ಮತ್ತು ಸೂಪರ್‌ಗ್ರೂಪ್‌ಗಳ ಬಗ್ಗೆ ಅಜ್ಞಾತ ವಿಷಯಗಳು
  • ಡೈಲಾಗ್‌ಗಳು ರೋಸ್ಟರ್‌ಗಿಂತ ಏಕೆ ಕೆಟ್ಟದಾಗಿದೆ
  • ಸಂಪೂರ್ಣ ವಿರುದ್ಧ ಸಂಬಂಧಿತ ಸಂದೇಶದ ವಿಳಾಸದ ಬಗ್ಗೆ
  • ಫೋಟೋ ಮತ್ತು ಚಿತ್ರದ ನಡುವಿನ ವ್ಯತ್ಯಾಸವೇನು
  • ಎಮೋಜಿಗಳು ಇಟಾಲಿಕ್ ಪಠ್ಯದೊಂದಿಗೆ ಹೇಗೆ ಮಧ್ಯಪ್ರವೇಶಿಸುತ್ತವೆ

ಮತ್ತು ಇತರ ಊರುಗೋಲುಗಳು! ಟ್ಯೂನ್ ಆಗಿರಿ!

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ