ಪೈಥಾನ್ನ ಅಸಿಂಕ್ಐಒ ಲೋ-ಲೆವೆಲ್ ನೆಟ್ವರ್ಕಿಂಗ್ ಅನ್ನು ಕರಗತ ಮಾಡಿಕೊಳ್ಳಿ. ಈ ಆಳವಾದ ವಿಶ್ಲೇಷಣೆಯು ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳನ್ನು ಒಳಗೊಂಡಿದ್ದು, ಉತ್ತಮ ಕಾರ್ಯಕ್ಷಮತೆ, ಕಸ್ಟಮ್ ನೆಟ್ವರ್ಕ್ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಗಳನ್ನು ನೀಡುತ್ತದೆ.
ಪೈಥಾನ್ನ Asyncio ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಅನ್ನು ಸರಳಗೊಳಿಸುವುದು: ಲೋ-ಲೆವೆಲ್ ನೆಟ್ವರ್ಕಿಂಗ್ನಲ್ಲಿ ಆಳವಾದ ವಿಶ್ಲೇಷಣೆ
ಆಧುನಿಕ ಪೈಥಾನ್ ಜಗತ್ತಿನಲ್ಲಿ, asyncio
ಉತ್ತಮ ಕಾರ್ಯಕ್ಷಮತೆಯ ನೆಟ್ವರ್ಕ್ ಪ್ರೋಗ್ರಾಮಿಂಗ್ನ ಮೂಲಾಧಾರವಾಗಿದೆ. ಡೆವಲಪರ್ಗಳು ಸಾಮಾನ್ಯವಾಗಿ async
ಮತ್ತು await
ಅನ್ನು aiohttp
ಅಥವಾ FastAPI
ನಂತಹ ಲೈಬ್ರರಿಗಳೊಂದಿಗೆ ಬಳಸಿಕೊಂಡು, ಪ್ರತಿಕ್ರಿಯಾತ್ಮಕ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಗಮನಾರ್ಹ ಸುಲಭವಾಗಿ ನಿರ್ಮಿಸಲು, ಅದರ ಸುಂದರವಾದ ಉನ್ನತ-ಮಟ್ಟದ API ಗಳೊಂದಿಗೆ ಪ್ರಾರಂಭಿಸುತ್ತಾರೆ. asyncio.open_connection()
ನಂತಹ ಕಾರ್ಯಗಳಿಂದ ಒದಗಿಸಲಾದ StreamReader
ಮತ್ತು StreamWriter
ಆಬ್ಜೆಕ್ಟ್ಗಳು ನೆಟ್ವರ್ಕ್ I/O ಅನ್ನು ನಿರ್ವಹಿಸಲು ಅದ್ಭುತವಾಗಿ ಸರಳವಾದ, ಅನುಕ್ರಮ ವಿಧಾನವನ್ನು ನೀಡುತ್ತವೆ. ಆದರೆ ಅಮೂರ್ತತೆಯು ಸಾಕಾಗದಿದ್ದಾಗ ಏನಾಗುತ್ತದೆ? ನೀವು ಸಂಕೀರ್ಣವಾದ, ಸ್ಥಿತಿಯುಕ್ತ, ಅಥವಾ ಪ್ರಮಾಣಿತವಲ್ಲದ ನೆಟ್ವರ್ಕ್ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಅಳವಡಿಸಲು ಬಯಸಿದರೆ ಏನು? ಅಂಡರ್ಲೈಯಿಂಗ್ ಸಂಪರ್ಕವನ್ನು ನೇರವಾಗಿ ನಿಯಂತ್ರಿಸುವ ಮೂಲಕ ಪ್ರತಿಯೊಂದು ಕಾರ್ಯಕ್ಷಮತೆಯ ಹನಿಗಳನ್ನು ಹೊರತೆಗೆಯಲು ನೀವು ಬಯಸಿದರೆ ಏನು? ಇಲ್ಲಿಯೇ ಅಸಿಂಕ್ಐಒದ ನೆಟ್ವರ್ಕಿಂಗ್ ಸಾಮರ್ಥ್ಯಗಳ ನಿಜವಾದ ಅಡಿಪಾಯ ಅಡಗಿದೆ: ಲೋ-ಲೆವೆಲ್ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ API. ಇದು ಮೊದಲಿಗೆ ಬೆದರಿಸುವಂತೆ ಕಾಣಿಸಬಹುದು, ಆದರೆ ಈ ಶಕ್ತಿಶಾಲಿ ಜೋಡಿಯನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ಹೊಸ ಮಟ್ಟದ ನಿಯಂತ್ರಣ ಮತ್ತು ನಮ್ಯತೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುತ್ತದೆ, ಇದರಿಂದ ನೀವು ಕಲ್ಪಿಸಿಕೊಳ್ಳಬಹುದಾದ ಯಾವುದೇ ನೆಟ್ವರ್ಕ್ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ನಿರ್ಮಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಈ ಸಮಗ್ರ ಮಾರ್ಗದರ್ಶಿ ಅಮೂರ್ತತೆಯ ಪದರಗಳನ್ನು ತೆರವುಗೊಳಿಸುತ್ತದೆ, ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳ ನಡುವಿನ ಸಹಜೀವನದ ಸಂಬಂಧವನ್ನು ಅನ್ವೇಷಿಸುತ್ತದೆ ಮತ್ತು ಪೈಥಾನ್ನಲ್ಲಿ ಲೋ-ಲೆವೆಲ್ ಅಸಮಕಾಲಿಕ ನೆಟ್ವರ್ಕಿಂಗ್ ಅನ್ನು ಕರಗತ ಮಾಡಿಕೊಳ್ಳಲು ನಿಮಗೆ ಅಧಿಕಾರ ನೀಡಲು ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಗಳ ಮೂಲಕ ನಿಮ್ಮನ್ನು ಕರೆದೊಯ್ಯುತ್ತದೆ.
Asyncio ನೆಟ್ವರ್ಕಿಂಗ್ನ ಎರಡು ಮುಖಗಳು: ಉನ್ನತ-ಮಟ್ಟದ ವಿರುದ್ಧ ಲೋ-ಲೆವೆಲ್
ನಾವು ಲೋ-ಲೆವೆಲ್ API ಗಳಿಗೆ ಆಳವಾಗಿ ಇಳಿಯುವ ಮೊದಲು, ಅಸಿಂಕ್ಐಒ ಪರಿಸರ ವ್ಯವಸ್ಥೆಯಲ್ಲಿ ಅವುಗಳ ಸ್ಥಾನವನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ನಿರ್ಣಾಯಕ. Asyncio ಬುದ್ಧಿವಂತಿಕೆಯಿಂದ ನೆಟ್ವರ್ಕ್ ಸಂವಹನಕ್ಕಾಗಿ ಎರಡು ವಿಭಿನ್ನ ಪದರಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ, ಪ್ರತಿಯೊಂದೂ ವಿಭಿನ್ನ ಬಳಕೆಯ ಸಂದರ್ಭಗಳಿಗೆ ತಕ್ಕಂತೆ ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿದೆ.
ಉನ್ನತ-ಮಟ್ಟದ API: ಸ್ಟ್ರೀಮ್ಗಳು
ಉನ್ನತ-ಮಟ್ಟದ API, ಸಾಮಾನ್ಯವಾಗಿ "ಸ್ಟ್ರೀಮ್ಗಳು" ಎಂದು ಕರೆಯಲ್ಪಡುತ್ತದೆ, ಇದು ಹೆಚ್ಚಿನ ಡೆವಲಪರ್ಗಳು ಮೊದಲು ಎದುರಿಸುವ ವಿಷಯವಾಗಿದೆ. ನೀವು asyncio.open_connection()
ಅಥವಾ asyncio.start_server()
ಅನ್ನು ಬಳಸಿದಾಗ, ನೀವು StreamReader
ಮತ್ತು StreamWriter
ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸುತ್ತೀರಿ. ಈ API ಅನ್ನು ಸರಳತೆ ಮತ್ತು ಬಳಕೆಯ ಸುಲಭತೆಗಾಗಿ ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿದೆ.
- ಅನಿವಾರ್ಯ ಶೈಲಿ: ಇದು ಅನುಕ್ರಮವಾಗಿ ಕಾಣುವ ಕೋಡ್ ಅನ್ನು ಬರೆಯಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. 100 ಬೈಟ್ಗಳನ್ನು ಪಡೆಯಲು ನೀವು
await reader.read(100)
ಅನ್ನು ಬಳಸುತ್ತೀರಿ, ನಂತರ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಕಳುಹಿಸಲುwriter.write(data)
ಅನ್ನು ಬಳಸುತ್ತೀರಿ. ಈasync/await
ಪ್ಯಾಟರ್ನ್ ಅರ್ಥಗರ್ಭಿತವಾಗಿದೆ ಮತ್ತು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಸುಲಭವಾಗಿದೆ. - ಅನುಕೂಲಕರ ಸಹಾಯಕರು: ಇದು
readuntil(separator)
ಮತ್ತುreadexactly(n)
ನಂತಹ ವಿಧಾನಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ, ಇದು ಸಾಮಾನ್ಯ ಫ್ರೇಮಿಂಗ್ ಕಾರ್ಯಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ, ಬಫರ್ಗಳನ್ನು ಹಸ್ತಚಾಲಿತವಾಗಿ ನಿರ್ವಹಿಸುವುದರಿಂದ ನಿಮ್ಮನ್ನು ಉಳಿಸುತ್ತದೆ. - ಆದರ್ಶ ಬಳಕೆಯ ಸಂದರ್ಭಗಳು: ಸರಳ ವಿನಂತಿ-ಪ್ರತಿಕ್ರಿಯೆ ಪ್ರೋಟೋಕಾಲ್ಗಳಿಗೆ (ಮೂಲಭೂತ HTTP ಕ್ಲೈಂಟ್ನಂತೆ), ಸಾಲು ಆಧಾರಿತ ಪ್ರೋಟೋಕಾಲ್ಗಳಿಗೆ (ರೆಡಿಸ್ ಅಥವಾ ಎಸ್ಎಂಟಿಪಿ ಯಂತೆ), ಅಥವಾ ಸಂವಹನವು ಊಹಿಸಬಹುದಾದ, ರೇಖೀಯ ಹರಿವನ್ನು ಅನುಸರಿಸುವ ಯಾವುದೇ ಪರಿಸ್ಥಿತಿಗೆ ಸೂಕ್ತವಾಗಿದೆ.
ಆದಾಗ್ಯೂ, ಈ ಸರಳತೆಯು ಒಂದು ವಿನಿಮಯದೊಂದಿಗೆ ಬರುತ್ತದೆ. ಸ್ವಯಂಪ್ರೇರಿತ ಸಂದೇಶಗಳು ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಬರಬಹುದಾದ ಹೆಚ್ಚು ಏಕಕಾಲಿಕ, ಈವೆಂಟ್-ಚಾಲಿತ ಪ್ರೋಟೋಕಾಲ್ಗಳಿಗೆ ಸ್ಟ್ರೀಮ್ ಆಧಾರಿತ ವಿಧಾನವು ಕಡಿಮೆ ಪರಿಣಾಮಕಾರಿಯಾಗಿರಬಹುದು. ಅನುಕ್ರಮ await
ಮಾದರಿಯು ಏಕಕಾಲಿಕ ಓದುವಿಕೆ ಮತ್ತು ಬರವಣಿಗೆಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಅಥವಾ ಸಂಕೀರ್ಣ ಸಂಪರ್ಕ ಸ್ಥಿತಿಗಳನ್ನು ನಿರ್ವಹಿಸಲು ತೊಡಕಾಗಿಸಬಹುದು.
ಲೋ-ಲೆವೆಲ್ API: ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳು
ಇದು ಉನ್ನತ-ಮಟ್ಟದ ಸ್ಟ್ರೀಮ್ಸ್ API ವಾಸ್ತವವಾಗಿ ನಿರ್ಮಿಸಲಾದ ಅಡಿಪಾಯದ ಪದರವಾಗಿದೆ. ಲೋ-ಲೆವೆಲ್ API ಎರಡು ವಿಭಿನ್ನ ಘಟಕಗಳನ್ನು ಆಧರಿಸಿದ ವಿನ್ಯಾಸ ಮಾದರಿಯನ್ನು ಬಳಸುತ್ತದೆ: ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳು.
- ಈವೆಂಟ್-ಚಾಲಿತ ಶೈಲಿ: ಡೇಟಾವನ್ನು ಪಡೆಯಲು ನೀವು ಕಾರ್ಯವನ್ನು ಕರೆಯುವ ಬದಲು, ಘಟನೆಗಳು ಸಂಭವಿಸಿದಾಗ (ಉದಾಹರಣೆಗೆ, ಸಂಪರ್ಕವನ್ನು ಮಾಡಲಾಗಿದೆ, ಡೇಟಾವನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ) ಅಸಿಂಕ್ಐಒ ನಿಮ್ಮ ಆಬ್ಜೆಕ್ಟ್ನಲ್ಲಿ ವಿಧಾನಗಳನ್ನು ಕರೆಯುತ್ತದೆ. ಇದು ಕಾಲ್ಬ್ಯಾಕ್ ಆಧಾರಿತ ವಿಧಾನವಾಗಿದೆ.
- ಕಳವಳಗಳ ಪ್ರತ್ಯೇಕತೆ: ಇದು "ಏನು" ಅನ್ನು "ಹೇಗೆ" ಯಿಂದ ಸ್ಪಷ್ಟವಾಗಿ ಪ್ರತ್ಯೇಕಿಸುತ್ತದೆ. ಪ್ರೋಟೋಕಾಲ್ ಡೇಟಾದೊಂದಿಗೆ ಏನು ಮಾಡಬೇಕೆಂದು (ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಲಾಜಿಕ್) ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ, ಆದರೆ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ನೆಟ್ವರ್ಕ್ ಮೂಲಕ ಡೇಟಾವನ್ನು ಹೇಗೆ ಕಳುಹಿಸಬೇಕು ಮತ್ತು ಸ್ವೀಕರಿಸಬೇಕು (I/O ಕಾರ್ಯವಿಧಾನ) ಎಂಬುದನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ.
- ಗರಿಷ್ಠ ನಿಯಂತ್ರಣ: ಈ API ಬಫರಿಂಗ್, ಫ್ಲೋ ಕಂಟ್ರೋಲ್ (ಬ್ಯಾಕ್ಪ್ರೆಶರ್) ಮತ್ತು ಸಂಪರ್ಕ ಜೀವನಚಕ್ರದ ಮೇಲೆ ನಿಮಗೆ ಉತ್ತಮ ನಿಯಂತ್ರಣವನ್ನು ನೀಡುತ್ತದೆ.
- ಆದರ್ಶ ಬಳಕೆಯ ಸಂದರ್ಭಗಳು: ಕಸ್ಟಮ್ ಬೈನರಿ ಅಥವಾ ಟೆಕ್ಸ್ಟ್ ಪ್ರೋಟೋಕಾಲ್ಗಳನ್ನು ಅಳವಡಿಸಲು, ಸಾವಿರಾರು ನಿರಂತರ ಸಂಪರ್ಕಗಳನ್ನು ನಿರ್ವಹಿಸುವ ಉತ್ತಮ-ಕಾರ್ಯಕ್ಷಮತೆಯ ಸರ್ವರ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು, ಅಥವಾ ನೆಟ್ವರ್ಕ್ ಫ್ರೇಮ್ವರ್ಕ್ಗಳು ಮತ್ತು ಲೈಬ್ರರಿಗಳನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸಲು ಇದು ಅತ್ಯಗತ್ಯ.
ಇದನ್ನು ಹೀಗೆ ಯೋಚಿಸಿ: ಸ್ಟ್ರೀಮ್ಸ್ API ಒಂದು ಊಟದ ಕಿಟ್ ಸೇವೆಯನ್ನು ಆರ್ಡರ್ ಮಾಡಿದಂತೆ. ನಿಮಗೆ ಪೂರ್ವ-ನಿಗದಿತ ಪದಾರ್ಥಗಳು ಮತ್ತು ಅನುಸರಿಸಲು ಸರಳವಾದ ಪಾಕವಿಧಾನ ಸಿಗುತ್ತದೆ. ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ API ಕಚ್ಚಾ ಪದಾರ್ಥಗಳೊಂದಿಗೆ ವೃತ್ತಿಪರ ಅಡುಗೆಮನೆಯಲ್ಲಿ ಶೆಫ್ ಆಗಿರುವಂತೆ ಮತ್ತು ಪ್ರಕ್ರಿಯೆಯ ಪ್ರತಿಯೊಂದು ಹಂತದ ಮೇಲೆ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವನ್ನು ಹೊಂದಿದಂತೆ. ಎರಡೂ ಉತ್ತಮ ಊಟವನ್ನು ಉತ್ಪಾದಿಸಬಹುದು, ಆದರೆ ಎರಡನೆಯದು ಅಪರಿಮಿತ ಸೃಜನಶೀಲತೆ ಮತ್ತು ನಿಯಂತ್ರಣವನ್ನು ನೀಡುತ್ತದೆ.
ಪ್ರಮುಖ ಘಟಕಗಳು: ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳ ಬಗ್ಗೆ ಹತ್ತಿರದ ನೋಟ
ಲೋ-ಲೆವೆಲ್ API ಯ ಶಕ್ತಿಯು ಪ್ರೋಟೋಕಾಲ್ ಮತ್ತು ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ನಡುವಿನ ಸೊಗಸಾದ ಸಂವಹನದಿಂದ ಬರುತ್ತದೆ. ಯಾವುದೇ ಲೋ-ಲೆವೆಲ್ ಅಸಿಂಕ್ಐಒ ನೆಟ್ವರ್ಕ್ ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ಅವು ವಿಭಿನ್ನ ಆದರೆ ಬೇರ್ಪಡಿಸಲಾಗದ ಪಾಲುದಾರರಾಗಿವೆ.
ಪ್ರೋಟೋಕಾಲ್: ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ನ ಮೆದುಳು
ಪ್ರೋಟೋಕಾಲ್ ಎಂಬುದು ನೀವು ಬರೆಯುವ ಒಂದು ವರ್ಗವಾಗಿದೆ. ಇದು asyncio.Protocol
(ಅಥವಾ ಅದರ ಒಂದು ರೂಪಾಂತರ) ನಿಂದ ಆನುವಂಶಿಕವಾಗಿ ಪಡೆಯುತ್ತದೆ ಮತ್ತು ಒಂದೇ ನೆಟ್ವರ್ಕ್ ಸಂಪರ್ಕವನ್ನು ನಿರ್ವಹಿಸಲು ಸ್ಥಿತಿ ಮತ್ತು ತರ್ಕವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. ನೀವು ಈ ವರ್ಗವನ್ನು ನೀವೇ ಇನ್ಸ್ಟ್ಯಾನ್ಶಿಯೇಟ್ ಮಾಡುವುದಿಲ್ಲ; ನೀವು ಅದನ್ನು ಅಸಿಂಕ್ಐಒಗೆ ಒದಗಿಸುತ್ತೀರಿ (ಉದಾಹರಣೆಗೆ, loop.create_server
ಗೆ), ಮತ್ತು ಅಸಿಂಕ್ಐಒ ಪ್ರತಿ ಹೊಸ ಕ್ಲೈಂಟ್ ಸಂಪರ್ಕಕ್ಕಾಗಿ ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ನ ಹೊಸ ನಿದರ್ಶನವನ್ನು ರಚಿಸುತ್ತದೆ.
ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ ವರ್ಗವನ್ನು ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲರ್ ವಿಧಾನಗಳ ಗುಂಪಿನಿಂದ ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ, ಇದನ್ನು ಈವೆಂಟ್ ಲೂಪ್ ಸಂಪರ್ಕದ ಜೀವನಚಕ್ರದಲ್ಲಿ ವಿವಿಧ ಹಂತಗಳಲ್ಲಿ ಕರೆಯುತ್ತದೆ. ಅತ್ಯಂತ ಮುಖ್ಯವಾದವುಗಳು:
connection_made(self, transport)
ಹೊಸ ಸಂಪರ್ಕವು ಯಶಸ್ವಿಯಾಗಿ ಸ್ಥಾಪಿತವಾದಾಗ ನಿಖರವಾಗಿ ಒಂದು ಬಾರಿ ಕರೆಯಲಾಗುತ್ತದೆ. ಇದು ನಿಮ್ಮ ಪ್ರವೇಶ ಬಿಂದು. ಇಲ್ಲಿ ನೀವು ಸಂಪರ್ಕವನ್ನು ಪ್ರತಿನಿಧಿಸುವ transport
ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಸ್ವೀಕರಿಸುತ್ತೀರಿ. ನೀವು ಯಾವಾಗಲೂ ಅದರ ಉಲ್ಲೇಖವನ್ನು ಉಳಿಸಬೇಕು, ಸಾಮಾನ್ಯವಾಗಿ self.transport
ಎಂದು. ಬಫರ್ಗಳನ್ನು ಹೊಂದಿಸುವುದು ಅಥವಾ ಪೀರ್ನ ವಿಳಾಸವನ್ನು ಲಾಗ್ ಮಾಡುವಂತಹ ಯಾವುದೇ ಪ್ರತಿ-ಸಂಪರ್ಕ ಪ್ರಾರಂಭಿಕ ಕಾರ್ಯವನ್ನು ನಿರ್ವಹಿಸಲು ಇದು ಸೂಕ್ತ ಸ್ಥಳವಾಗಿದೆ.
data_received(self, data)
ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ನ ಹೃದಯಭಾಗ. ಸಂಪರ್ಕದ ಇನ್ನೊಂದು ತುದಿಯಿಂದ ಹೊಸ ಡೇಟಾ ಬಂದಾಗಲೆಲ್ಲಾ ಈ ವಿಧಾನವನ್ನು ಕರೆಯಲಾಗುತ್ತದೆ. data
ಆರ್ಗ್ಯುಮೆಂಟ್ ಒಂದು bytes
ಆಬ್ಜೆಕ್ಟ್ ಆಗಿದೆ. TCP ಒಂದು ಸ್ಟ್ರೀಮ್ ಪ್ರೋಟೋಕಾಲ್ ಆಗಿದೆ, ಸಂದೇಶ ಪ್ರೋಟೋಕಾಲ್ ಅಲ್ಲ ಎಂಬುದನ್ನು ನೆನಪಿಟ್ಟುಕೊಳ್ಳುವುದು ಬಹಳ ಮುಖ್ಯ. ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ನಿಂದ ಒಂದು ಏಕೈಕ ತಾರ್ಕಿಕ ಸಂದೇಶವು ಅನೇಕ data_received
ಕರೆಗಳಲ್ಲಿ ವಿಭಜಿಸಬಹುದು, ಅಥವಾ ಅನೇಕ ಸಣ್ಣ ಸಂದೇಶಗಳನ್ನು ಒಂದೇ ಕರೆಗೆ ಬಂಡಲ್ ಮಾಡಬಹುದು. ನಿಮ್ಮ ಕೋಡ್ ಈ ಬಫರಿಂಗ್ ಮತ್ತು ಪಾರ್ಸಿಂಗ್ ಅನ್ನು ನಿರ್ವಹಿಸಬೇಕು.
connection_lost(self, exc)
ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಿದಾಗ ಕರೆಯಲಾಗುತ್ತದೆ. ಇದು ಹಲವಾರು ಕಾರಣಗಳಿಂದ ಸಂಭವಿಸಬಹುದು. ಸಂಪರ್ಕವನ್ನು ಸ್ವಚ್ಛವಾಗಿ ಮುಚ್ಚಿದರೆ (ಉದಾಹರಣೆಗೆ, ಇನ್ನೊಂದು ಕಡೆ ಅದನ್ನು ಮುಚ್ಚುತ್ತದೆ, ಅಥವಾ ನೀವು transport.close()
ಅನ್ನು ಕರೆಯುತ್ತೀರಿ), exc
None
ಆಗಿರುತ್ತದೆ. ದೋಷದಿಂದಾಗಿ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಿದರೆ (ಉದಾಹರಣೆಗೆ, ನೆಟ್ವರ್ಕ್ ವೈಫಲ್ಯ, ಮರುಹೊಂದಿಸುವಿಕೆ), exc
ದೋಷವನ್ನು ವಿವರಿಸುವ ಎಕ್ಸೆಪ್ಶನ್ ಆಬ್ಜೆಕ್ಟ್ ಆಗಿರುತ್ತದೆ. ಸ್ವಚ್ಛಗೊಳಿಸುವಿಕೆ, ಸಂಪರ್ಕ ಕಡಿತವನ್ನು ಲಾಗ್ ಮಾಡುವುದು ಅಥವಾ ನೀವು ಕ್ಲೈಂಟ್ ಅನ್ನು ನಿರ್ಮಿಸುತ್ತಿದ್ದರೆ ಮರುಸಂಪರ್ಕಿಸಲು ಪ್ರಯತ್ನಿಸಲು ಇದು ನಿಮ್ಮ ಅವಕಾಶವಾಗಿದೆ.
eof_received(self)
ಇದು ಹೆಚ್ಚು ಸೂಕ್ಷ್ಮವಾದ ಕಾಲ್ಬ್ಯಾಕ್. ಇನ್ನೊಂದು ತುದಿಯು ಇನ್ನು ಮುಂದೆ ಯಾವುದೇ ಡೇಟಾವನ್ನು ಕಳುಹಿಸುವುದಿಲ್ಲ ಎಂದು ಸಂಕೇತಿಸಿದಾಗ (ಉದಾಹರಣೆಗೆ, POSIX ಸಿಸ್ಟಮ್ನಲ್ಲಿ shutdown(SHUT_WR)
ಅನ್ನು ಕರೆಯುವ ಮೂಲಕ) ಇದನ್ನು ಕರೆಯಲಾಗುತ್ತದೆ, ಆದರೆ ನೀವು ಡೇಟಾವನ್ನು ಕಳುಹಿಸಲು ಸಂಪರ್ಕವು ಇನ್ನೂ ತೆರೆದಿರಬಹುದು. ನೀವು ಈ ವಿಧಾನದಿಂದ True
ಅನ್ನು ಹಿಂತಿರುಗಿಸಿದರೆ, ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಮುಚ್ಚಲ್ಪಡುತ್ತದೆ. ನೀವು False
(ಡಿಫಾಲ್ಟ್) ಅನ್ನು ಹಿಂತಿರುಗಿಸಿದರೆ, ನಂತರ ನೀವೇ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಅನ್ನು ಮುಚ್ಚುವ ಜವಾಬ್ದಾರಿ ನಿಮ್ಮದಾಗಿರುತ್ತದೆ.
ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್: ಸಂವಹನ ಚಾನಲ್
ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಅಸಿಂಕ್ಐಒ ಒದಗಿಸಿದ ಆಬ್ಜೆಕ್ಟ್ ಆಗಿದೆ. ನೀವು ಅದನ್ನು ರಚಿಸುವುದಿಲ್ಲ; ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ನ connection_made
ವಿಧಾನದಲ್ಲಿ ನೀವು ಅದನ್ನು ಸ್ವೀಕರಿಸುತ್ತೀರಿ. ಇದು ಅಂಡರ್ಲೈಯಿಂಗ್ ನೆಟ್ವರ್ಕ್ ಸಾಕೆಟ್ ಮತ್ತು ಈವೆಂಟ್ ಲೂಪ್ನ I/O ವೇಳಾಪಟ್ಟಿಯ ಮೇಲೆ ಉನ್ನತ-ಮಟ್ಟದ ಅಮೂರ್ತತೆಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಡೇಟಾವನ್ನು ಕಳುಹಿಸುವುದು ಮತ್ತು ಸಂಪರ್ಕದ ನಿಯಂತ್ರಣವನ್ನು ನಿರ್ವಹಿಸುವುದು ಇದರ ಪ್ರಾಥಮಿಕ ಕೆಲಸವಾಗಿದೆ.
ನೀವು ಅದರ ವಿಧಾನಗಳ ಮೂಲಕ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ನೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸುತ್ತೀರಿ:
transport.write(data)
ಡೇಟಾವನ್ನು ಕಳುಹಿಸಲು ಪ್ರಾಥಮಿಕ ವಿಧಾನ. data
ಒಂದು bytes
ಆಬ್ಜೆಕ್ಟ್ ಆಗಿರಬೇಕು. ಈ ವಿಧಾನವು ನಾನ್-ಬ್ಲಾಕಿಂಗ್ ಆಗಿದೆ. ಇದು ಡೇಟಾವನ್ನು ತಕ್ಷಣವೇ ಕಳುಹಿಸುವುದಿಲ್ಲ. ಬದಲಿಗೆ, ಇದು ಡೇಟಾವನ್ನು ಆಂತರಿಕ ಬರೆಯುವ ಬಫರ್ಗೆ ಇರಿಸುತ್ತದೆ, ಮತ್ತು ಈವೆಂಟ್ ಲೂಪ್ ಅದನ್ನು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಸಾಧ್ಯವಾದಷ್ಟು ಪರಿಣಾಮಕಾರಿಯಾಗಿ ನೆಟ್ವರ್ಕ್ ಮೂಲಕ ಕಳುಹಿಸುತ್ತದೆ.
transport.writelines(list_of_data)
ಒಂದೇ ಬಾರಿಗೆ ಬಫರ್ಗೆ bytes
ಆಬ್ಜೆಕ್ಟ್ಗಳ ಅನುಕ್ರಮವನ್ನು ಬರೆಯಲು ಹೆಚ್ಚು ಪರಿಣಾಮಕಾರಿ ಮಾರ್ಗ, ಇದು ಸಿಸ್ಟಮ್ ಕರೆಗಳ ಸಂಖ್ಯೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುವ ಸಾಧ್ಯತೆಯಿದೆ.
transport.close()
ಇದು ಸುಲಲಿತವಾದ ಶಟ್ಡೌನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ. ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಮೊದಲು ಅದರ ರೈಟ್ ಬಫರ್ನಲ್ಲಿ ಉಳಿದಿರುವ ಯಾವುದೇ ಡೇಟಾವನ್ನು ಫ್ಲಶ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ನಂತರ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚುತ್ತದೆ. close()
ಅನ್ನು ಕರೆದ ನಂತರ ಯಾವುದೇ ಡೇಟಾವನ್ನು ಬರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ.
transport.abort()
ಇದು ಹಾರ್ಡ್ ಶಟ್ಡೌನ್ ಅನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ. ಸಂಪರ್ಕವನ್ನು ತಕ್ಷಣವೇ ಮುಚ್ಚಲಾಗುತ್ತದೆ, ಮತ್ತು ರೈಟ್ ಬಫರ್ನಲ್ಲಿ ಬಾಕಿ ಉಳಿದಿರುವ ಯಾವುದೇ ಡೇಟಾವನ್ನು ತಿರಸ್ಕರಿಸಲಾಗುತ್ತದೆ. ಇದನ್ನು ಅಸಾಧಾರಣ ಸಂದರ್ಭಗಳಲ್ಲಿ ಬಳಸಬೇಕು.
transport.get_extra_info(name, default=None)
ಒಳನೋಟಕ್ಕೆ ಅತ್ಯಂತ ಉಪಯುಕ್ತವಾದ ವಿಧಾನ. ನೀವು ಸಂಪರ್ಕದ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಬಹುದು, ಉದಾಹರಣೆಗೆ ಪೀರ್ನ ವಿಳಾಸ ('peername'
), ಅಂಡರ್ಲೈಯಿಂಗ್ ಸಾಕೆಟ್ ಆಬ್ಜೆಕ್ಟ್ ('socket'
), ಅಥವಾ SSL/TLS ಪ್ರಮಾಣಪತ್ರ ಮಾಹಿತಿ ('ssl_object'
).
ಸಹಜೀವನ ಸಂಬಂಧ
ಈ ವಿನ್ಯಾಸದ ಸೌಂದರ್ಯವು ಮಾಹಿತಿಯ ಸ್ಪಷ್ಟ, ಆವರ್ತಕ ಹರಿವಿನಲ್ಲಿದೆ:
- ಸೆಟಪ್: ಈವೆಂಟ್ ಲೂಪ್ ಹೊಸ ಸಂಪರ್ಕವನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ.
- ಇನ್ಸ್ಟ್ಯಾನ್ಶಿಯೇಷನ್: ಲೂಪ್ ನಿಮ್ಮ
Protocol
ವರ್ಗದ ನಿದರ್ಶನವನ್ನು ಮತ್ತು ಸಂಪರ್ಕವನ್ನು ಪ್ರತಿನಿಧಿಸುವTransport
ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ. - ಸಂಪರ್ಕ: ಲೂಪ್
your_protocol.connection_made(transport)
ಅನ್ನು ಕರೆಯುತ್ತದೆ, ಎರಡು ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು ಒಟ್ಟಿಗೆ ಸಂಪರ್ಕಿಸುತ್ತದೆ. ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ ಈಗ ಡೇಟಾವನ್ನು ಕಳುಹಿಸಲು ಒಂದು ಮಾರ್ಗವನ್ನು ಹೊಂದಿದೆ. - ಡೇಟಾ ಸ್ವೀಕರಿಸುವಿಕೆ: ನೆಟ್ವರ್ಕ್ ಸಾಕೆಟ್ನಲ್ಲಿ ಡೇಟಾ ಬಂದಾಗ, ಈವೆಂಟ್ ಲೂಪ್ ಎಚ್ಚರಗೊಳ್ಳುತ್ತದೆ, ಡೇಟಾವನ್ನು ಓದುತ್ತದೆ ಮತ್ತು
your_protocol.data_received(data)
ಅನ್ನು ಕರೆಯುತ್ತದೆ. - ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವಿಕೆ: ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ನ ತರ್ಕವು ಸ್ವೀಕರಿಸಿದ ಡೇಟಾವನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುತ್ತದೆ.
- ಡೇಟಾ ಕಳುಹಿಸುವಿಕೆ: ಅದರ ತರ್ಕದ ಆಧಾರದ ಮೇಲೆ, ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ ಪ್ರತ್ಯುತ್ತರವನ್ನು ಕಳುಹಿಸಲು
self.transport.write(response_data)
ಅನ್ನು ಕರೆಯುತ್ತದೆ. ಡೇಟಾವನ್ನು ಬಫರ್ ಮಾಡಲಾಗುತ್ತದೆ. - ಹಿನ್ನೆಲೆ I/O: ಈವೆಂಟ್ ಲೂಪ್ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಮೂಲಕ ಬಫರ್ ಮಾಡಿದ ಡೇಟಾದ ನಾನ್-ಬ್ಲಾಕಿಂಗ್ ಕಳುಹಿಸುವಿಕೆಯನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ.
- ಟೆರ್ಡೌನ್: ಸಂಪರ್ಕವು ಕೊನೆಗೊಂಡಾಗ, ಈವೆಂಟ್ ಲೂಪ್ ಅಂತಿಮ ಶುಚೀಕರಣಕ್ಕಾಗಿ
your_protocol.connection_lost(exc)
ಅನ್ನು ಕರೆಯುತ್ತದೆ.
ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಯನ್ನು ನಿರ್ಮಿಸುವುದು: ಎಕೋ ಸರ್ವರ್ ಮತ್ತು ಕ್ಲೈಂಟ್
ಸಿದ್ಧಾಂತವು ಉತ್ತಮವಾಗಿದೆ, ಆದರೆ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಉತ್ತಮ ಮಾರ್ಗವೆಂದರೆ ಏನನ್ನಾದರೂ ನಿರ್ಮಿಸುವುದು. ಕ್ಲಾಸಿಕ್ ಎಕೋ ಸರ್ವರ್ ಮತ್ತು ಅದಕ್ಕೆ ಅನುಗುಣವಾದ ಕ್ಲೈಂಟ್ ಅನ್ನು ರಚಿಸೋಣ. ಸರ್ವರ್ ಸಂಪರ್ಕಗಳನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ ಮತ್ತು ಅದು ಸ್ವೀಕರಿಸಿದ ಯಾವುದೇ ಡೇಟಾವನ್ನು ಸರಳವಾಗಿ ಹಿಂತಿರುಗಿಸುತ್ತದೆ.
ಎಕೋ ಸರ್ವರ್ ಅಳವಡಿಕೆ
ಮೊದಲಿಗೆ, ನಾವು ನಮ್ಮ ಸರ್ವರ್-ಸೈಡ್ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೇವೆ. ಇದು ಗಮನಾರ್ಹವಾಗಿ ಸರಳವಾಗಿದೆ, ಕೋರ್ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲರ್ಗಳನ್ನು ಪ್ರದರ್ಶಿಸುತ್ತದೆ.
import asyncio
class EchoServerProtocol(asyncio.Protocol):
def connection_made(self, transport):
# ಹೊಸ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿದೆ.
# ಲಾಗಿಂಗ್ಗಾಗಿ ರಿಮೋಟ್ ವಿಳಾಸವನ್ನು ಪಡೆಯಿರಿ.
peername = transport.get_extra_info('peername')
print(f"Connection from: {peername}")
# ನಂತರದ ಬಳಕೆಗಾಗಿ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಅನ್ನು ಸಂಗ್ರಹಿಸಿ.
self.transport = transport
def data_received(self, data):
# ಕ್ಲೈಂಟ್ನಿಂದ ಡೇಟಾ ಸ್ವೀಕರಿಸಲಾಗಿದೆ.
message = data.decode()
print(f"Data received: {message.strip()}")
# ಕ್ಲೈಂಟ್ಗೆ ಡೇಟಾವನ್ನು ಹಿಂತಿರುಗಿಸಿ (Echo).
print(f"Echoing back: {message.strip()}")
self.transport.write(data)
def connection_lost(self, exc):
# ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಲಾಗಿದೆ.
print("Connection closed.")
# ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಮುಚ್ಚಲ್ಪಡುತ್ತದೆ, ಇಲ್ಲಿ self.transport.close() ಅನ್ನು ಕರೆಯುವ ಅಗತ್ಯವಿಲ್ಲ.
async def main_server():
# ನಾವು ಸರ್ವರ್ ಅನ್ನು ಅನಿರ್ದಿಷ್ಟವಾಗಿ ಚಲಾಯಿಸಲು ಯೋಜಿಸಿರುವುದರಿಂದ ಈವೆಂಟ್ ಲೂಪ್ಗೆ ಉಲ್ಲೇಖವನ್ನು ಪಡೆಯಿರಿ.
loop = asyncio.get_running_loop()
host = '127.0.0.1'
port = 8888
# `create_server` ಕರೋಟಿನ್ ಸರ್ವರ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ ಮತ್ತು ಪ್ರಾರಂಭಿಸುತ್ತದೆ.
# ಮೊದಲ ಆರ್ಗ್ಯುಮೆಂಟ್ protocol_factory ಆಗಿದೆ, ಇದು ಹೊಸ ಪ್ರೋಟೋಕಾಲ್ ನಿದರ್ಶನವನ್ನು ಹಿಂತಿರುಗಿಸುವ ಕರೆಯಬಹುದಾದ ವಸ್ತುವಾಗಿದೆ.
# ನಮ್ಮ ಸಂದರ್ಭದಲ್ಲಿ, `EchoServerProtocol` ವರ್ಗವನ್ನು ಸರಳವಾಗಿ ಪಾಸ್ ಮಾಡುವುದು ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ.
server = await loop.create_server(
lambda: EchoServerProtocol(),
host,
port)
addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
print(f'Serving on {addrs}')
# ಸರ್ವರ್ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಮುಖ್ಯ ಕರೋಟಿನ್ ಜೀವಂತವಾಗಿಡಲು,
# ನಾವು ಹೊಸ ಫ್ಯೂಚರ್ನಂತೆ ಎಂದಿಗೂ ಪೂರ್ಣಗೊಳ್ಳದ ಯಾವುದನ್ನಾದರೂ ನಿರೀಕ್ಷಿಸಬಹುದು.
# ಈ ಉದಾಹರಣೆಗಾಗಿ, ನಾವು ಅದನ್ನು "ಶಾಶ್ವತವಾಗಿ" ಚಲಾಯಿಸುತ್ತೇವೆ.
async with server:
await server.serve_forever()
if __name__ == "__main__":
try:
# ಸರ್ವರ್ ಅನ್ನು ಚಲಾಯಿಸಲು:
asyncio.run(main_server())
except KeyboardInterrupt:
print("Server shut down.")
ಈ ಸರ್ವರ್ ಕೋಡ್ನಲ್ಲಿ, loop.create_server()
ಪ್ರಮುಖವಾಗಿದೆ. ಇದು ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಹೋಸ್ಟ್ ಮತ್ತು ಪೋರ್ಟ್ಗೆ ಬಂಧಿಸುತ್ತದೆ ಮತ್ತು ಹೊಸ ಸಂಪರ್ಕಗಳಿಗಾಗಿ ಕೇಳಲು ಈವೆಂಟ್ ಲೂಪ್ಗೆ ಹೇಳುತ್ತದೆ. ಪ್ರತಿ ಒಳಬರುವ ಸಂಪರ್ಕಕ್ಕಾಗಿ, ಅದು ನಮ್ಮ protocol_factory
(lambda: EchoServerProtocol()
ಕಾರ್ಯ) ಅನ್ನು ಕರೆಯುತ್ತದೆ, ಆ ನಿರ್ದಿಷ್ಟ ಕ್ಲೈಂಟ್ಗೆ ಮೀಸಲಾದ ತಾಜಾ ಪ್ರೋಟೋಕಾಲ್ ನಿದರ್ಶನವನ್ನು ರಚಿಸಲು.
ಎಕೋ ಕ್ಲೈಂಟ್ ಅಳವಡಿಕೆ
ಕ್ಲೈಂಟ್ ಪ್ರೋಟೋಕಾಲ್ ಸ್ವಲ್ಪ ಹೆಚ್ಚು ಒಳಗೊಂಡಿರುತ್ತದೆ ಏಕೆಂದರೆ ಅದು ತನ್ನದೇ ಆದ ಸ್ಥಿತಿಯನ್ನು ನಿರ್ವಹಿಸಬೇಕಾಗುತ್ತದೆ: ಯಾವ ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಬೇಕು ಮತ್ತು ಅದು ತನ್ನ ಕೆಲಸವನ್ನು ಯಾವಾಗ "ಮುಗಿಸಿದೆ" ಎಂದು ಪರಿಗಣಿಸುತ್ತದೆ. ಕ್ಲೈಂಟ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಮುಖ್ಯ ಕರೋಟಿನ್ಗೆ ಪೂರ್ಣಗೊಳಿಸುವಿಕೆಯನ್ನು ಸಂಕೇತಿಸಲು asyncio.Future
ಅಥವಾ asyncio.Event
ಅನ್ನು ಬಳಸುವುದು ಸಾಮಾನ್ಯ ಮಾದರಿಯಾಗಿದೆ.
import asyncio
class EchoClientProtocol(asyncio.Protocol):
def __init__(self, message, on_con_lost):
self.message = message
self.on_con_lost = on_con_lost
self.transport = None
def connection_made(self, transport):
self.transport = transport
print(f"Sending: {self.message}")
self.transport.write(self.message.encode())
def data_received(self, data):
print(f"Received echo: {data.decode().strip()}")
def connection_lost(self, exc):
print("The server closed the connection")
# ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ ಮತ್ತು ಕಾರ್ಯ ಪೂರ್ಣಗೊಂಡಿದೆ ಎಂದು ಸಂಕೇತಿಸಿ.
self.on_con_lost.set_result(True)
def eof_received(self):
# ಸರ್ವರ್ ಮುಚ್ಚುವ ಮೊದಲು EOF ಕಳುಹಿಸಿದರೆ ಇದನ್ನು ಕರೆಯಬಹುದು.
print("Received EOF from server.")
async def main_client():
loop = asyncio.get_running_loop()
# ಕ್ಲೈಂಟ್ನ ಕೆಲಸದ ಪೂರ್ಣಗೊಳಿಸುವಿಕೆಯನ್ನು ಸಂಕೇತಿಸಲು on_con_lost ಫ್ಯೂಚರ್ ಅನ್ನು ಬಳಸಲಾಗುತ್ತದೆ.
on_con_lost = loop.create_future()
message = "Hello World!"
host = '127.0.0.1'
port = 8888
# `create_connection` ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸುತ್ತದೆ ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಲಿಂಕ್ ಮಾಡುತ್ತದೆ.
try:
transport, protocol = await loop.create_connection(
lambda: EchoClientProtocol(message, on_con_lost),
host,
port)
except ConnectionRefusedError:
print("Connection refused. Is the server running?")
return
# ಪ್ರೋಟೋಕಾಲ್ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ ಎಂದು ಸಂಕೇತಿಸುವವರೆಗೆ ಕಾಯಿರಿ.
try:
await on_con_lost
finally:
# ಸೌಮ್ಯವಾಗಿ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಅನ್ನು ಮುಚ್ಚಿ.
transport.close()
if __name__ == "__main__":
# ಕ್ಲೈಂಟ್ ಅನ್ನು ಚಲಾಯಿಸಲು:
# ಮೊದಲು, ಒಂದು ಟರ್ಮಿನಲ್ನಲ್ಲಿ ಸರ್ವರ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿ.
# ನಂತರ, ಇನ್ನೊಂದು ಟರ್ಮಿನಲ್ನಲ್ಲಿ ಈ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಚಲಾಯಿಸಿ.
asyncio.run(main_client())
ಇಲ್ಲಿ, loop.create_connection()
ಎಂಬುದು create_server
ಗೆ ಕ್ಲೈಂಟ್-ಸೈಡ್ ಪ್ರತಿರೂಪವಾಗಿದೆ. ಇದು ನೀಡಿರುವ ವಿಳಾಸಕ್ಕೆ ಸಂಪರ್ಕಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ. ಯಶಸ್ವಿಯಾದರೆ, ಅದು ನಮ್ಮ EchoClientProtocol
ಅನ್ನು ಇನ್ಸ್ಟ್ಯಾನ್ಶಿಯೇಟ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಅದರ connection_made
ವಿಧಾನವನ್ನು ಕರೆಯುತ್ತದೆ. on_con_lost
ಫ್ಯೂಚರ್ನ ಬಳಕೆಯು ಒಂದು ನಿರ್ಣಾಯಕ ಮಾದರಿಯಾಗಿದೆ. main_client
ಕರೋಟಿನ್ ಈ ಫ್ಯೂಚರ್ ಅನ್ನು await
ಮಾಡುತ್ತದೆ, ಇದರಿಂದ connection_lost
ನಿಂದ on_con_lost.set_result(True)
ಅನ್ನು ಕರೆಯುವ ಮೂಲಕ ಪ್ರೋಟೋಕಾಲ್ ತನ್ನ ಕೆಲಸ ಮುಗಿದಿದೆ ಎಂದು ಸಂಕೇತಿಸುವವರೆಗೆ ತನ್ನದೇ ಆದ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯನ್ನು ಪರಿಣಾಮಕಾರಿಯಾಗಿ ನಿಲ್ಲಿಸುತ್ತದೆ.
ಸುಧಾರಿತ ಪರಿಕಲ್ಪನೆಗಳು ಮತ್ತು ನೈಜ-ಪ್ರಪಂಚದ ಸನ್ನಿವೇಶಗಳು
ಎಕೋ ಉದಾಹರಣೆಯು ಮೂಲಭೂತ ಅಂಶಗಳನ್ನು ಒಳಗೊಂಡಿದೆ, ಆದರೆ ನೈಜ-ಪ್ರಪಂಚದ ಪ್ರೋಟೋಕಾಲ್ಗಳು ವಿರಳವಾಗಿ ಅಷ್ಟು ಸರಳವಾಗಿರುತ್ತವೆ. ನೀವು ಅನಿವಾರ್ಯವಾಗಿ ಎದುರಿಸುವ ಕೆಲವು ಹೆಚ್ಚು ಸುಧಾರಿತ ವಿಷಯಗಳನ್ನು ಅನ್ವೇಷಿಸೋಣ.
ಸಂದೇಶ ಫ್ರೇಮಿಂಗ್ ಮತ್ತು ಬಫರಿಂಗ್ ಅನ್ನು ನಿರ್ವಹಿಸುವುದು
ಮೂಲಭೂತ ಅಂಶಗಳ ನಂತರ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಬೇಕಾದ ಏಕೈಕ ಪ್ರಮುಖ ಪರಿಕಲ್ಪನೆಯೆಂದರೆ TCP ಎಂಬುದು ಬೈಟ್ಗಳ ಸ್ಟ್ರೀಮ್ ಆಗಿದೆ. ಯಾವುದೇ ಸಹಜ "ಸಂದೇಶ" ಗಡಿಗಳಿಲ್ಲ. ಕ್ಲೈಂಟ್ "Hello" ಮತ್ತು ನಂತರ "World" ಅನ್ನು ಕಳುಹಿಸಿದರೆ, ನಿಮ್ಮ ಸರ್ವರ್ನ data_received
ಅನ್ನು b'HelloWorld'
ನೊಂದಿಗೆ ಒಂದು ಬಾರಿ, b'Hello'
ಮತ್ತು b'World'
ನೊಂದಿಗೆ ಎರಡು ಬಾರಿ, ಅಥವಾ ಭಾಗಶಃ ಡೇಟಾದೊಂದಿಗೆ ಹಲವು ಬಾರಿ ಕರೆಯಬಹುದು.
ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ "ಫ್ರೇಮಿಂಗ್" ಗೆ ಜವಾಬ್ದಾರವಾಗಿದೆ - ಈ ಬೈಟ್ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಅರ್ಥಪೂರ್ಣ ಸಂದೇಶಗಳಾಗಿ ಪುನಃ ಜೋಡಿಸುವುದು. ಡಿಲಿಮಿಟರ್, ಉದಾಹರಣೆಗೆ ಹೊಸ ಸಾಲು ಅಕ್ಷರ (\n
) ಅನ್ನು ಬಳಸುವುದು ಸಾಮಾನ್ಯ ತಂತ್ರವಾಗಿದೆ.
ಇಲ್ಲಿ ಹೊಸ ಸಾಲನ್ನು ಕಂಡುಕೊಳ್ಳುವವರೆಗೆ ಡೇಟಾವನ್ನು ಬಫರ್ ಮಾಡುವ, ಒಂದು ಸಮಯದಲ್ಲಿ ಒಂದು ಸಾಲನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವ ಮಾರ್ಪಡಿಸಿದ ಪ್ರೋಟೋಕಾಲ್ ಇದೆ.
class LineBasedProtocol(asyncio.Protocol):
def __init__(self):
self._buffer = b''
self.transport = None
def connection_made(self, transport):
self.transport = transport
print("Connection established.")
def data_received(self, data):
# ಆಂತರಿಕ ಬಫರ್ಗೆ ಹೊಸ ಡೇಟಾವನ್ನು ಸೇರಿಸಿ
self._buffer += data
# ಬಫರ್ನಲ್ಲಿರುವಷ್ಟು ಪೂರ್ಣ ಸಾಲುಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಿ
while b'\n' in self._buffer:
line, self._buffer = self._buffer.split(b'\n', 1)
self.process_line(line.decode().strip())
def process_line(self, line):
# ಇದು ಒಂದೇ ಸಂದೇಶಕ್ಕಾಗಿ ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ತರ್ಕ ಇರುವ ಸ್ಥಳ
print(f"Processing complete message: {line}")
response = f"Processed: {line}\n"
self.transport.write(response.encode())
def connection_lost(self, exc):
print("Connection lost.")
ಫ್ಲೋ ಕಂಟ್ರೋಲ್ (ಬ್ಯಾಕ್ಪ್ರೆಶರ್) ನಿರ್ವಹಿಸುವುದು
ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ನೆಟ್ವರ್ಕ್ ಅಥವಾ ರಿಮೋಟ್ ಪೀರ್ ನಿರ್ವಹಿಸುವುದಕ್ಕಿಂತ ವೇಗವಾಗಿ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗೆ ಡೇಟಾವನ್ನು ಬರೆಯುತ್ತಿದ್ದರೆ ಏನಾಗುತ್ತದೆ? ಡೇಟಾ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ನ ಆಂತರಿಕ ಬಫರ್ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗುತ್ತದೆ. ಇದು ಪರೀಕ್ಷಿಸದೆ ಮುಂದುವರಿದರೆ, ಬಫರ್ ಅನಿರ್ದಿಷ್ಟವಾಗಿ ಬೆಳೆಯಬಹುದು, ಎಲ್ಲಾ ಲಭ್ಯವಿರುವ ಮೆಮೊರಿಯನ್ನು ಸೇವಿಸಬಹುದು. ಈ ಸಮಸ್ಯೆಯನ್ನು "ಬ್ಯಾಕ್ಪ್ರೆಶರ್" ಕೊರತೆ ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ.
ಇದನ್ನು ನಿರ್ವಹಿಸಲು ಅಸಿಂಕ್ಐಒ ಒಂದು ಕಾರ್ಯವಿಧಾನವನ್ನು ಒದಗಿಸುತ್ತದೆ. ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ತನ್ನದೇ ಆದ ಬಫರ್ ಗಾತ್ರವನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುತ್ತದೆ. ಬಫರ್ ಒಂದು ನಿರ್ದಿಷ್ಟ ಹೈ-ವಾಟರ್ ಮಾರ್ಕ್ ಅನ್ನು ಮೀರಿ ಬೆಳೆದಾಗ, ಈವೆಂಟ್ ಲೂಪ್ ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ನ pause_writing()
ವಿಧಾನವನ್ನು ಕರೆಯುತ್ತದೆ. ಇದು ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ಗೆ ಡೇಟಾವನ್ನು ಕಳುಹಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಲು ಸಂಕೇತವಾಗಿದೆ. ಬಫರ್ ಲೋ-ವಾಟರ್ ಮಾರ್ಕ್ ಕೆಳಗೆ ಬರಿದಾದಾಗ, ಲೂಪ್ resume_writing()
ಅನ್ನು ಕರೆಯುತ್ತದೆ, ಡೇಟಾವನ್ನು ಮತ್ತೆ ಕಳುಹಿಸುವುದು ಸುರಕ್ಷಿತ ಎಂದು ಸಂಕೇತಿಸುತ್ತದೆ.
class FlowControlledProtocol(asyncio.Protocol):
def __init__(self):
self._paused = False
self._data_source = some_data_generator() # ಡೇಟಾದ ಮೂಲವನ್ನು ಊಹಿಸಿ
self.transport = None
def connection_made(self, transport):
self.transport = transport
self.resume_writing() # ಬರೆಯುವ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ
def pause_writing(self):
# ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಬಫರ್ ತುಂಬಿದೆ.
print("Pausing writing.")
self._paused = True
def resume_writing(self):
# ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಬಫರ್ ಬರಿದಾಗಿದೆ.
print("Resuming writing.")
self._paused = False
self._write_more_data()
def _write_more_data(self):
# ಇದು ನಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ನ ರೈಟ್ ಲೂಪ್.
while not self._paused:
try:
data = next(self._data_source)
self.transport.write(data)
except StopIteration:
self.transport.close()
break # ಕಳುಹಿಸಲು ಯಾವುದೇ ಡೇಟಾ ಇಲ್ಲ
# ನಾವು ತಕ್ಷಣವೇ ವಿರಾಮಗೊಳಿಸಬೇಕೆ ಎಂದು ನೋಡಲು ಬಫರ್ ಗಾತ್ರವನ್ನು ಪರಿಶೀಲಿಸಿ
if self.transport.get_write_buffer_size() > 0:
self.pause_writing()
TCP ಮೀರಿದ: ಇತರ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು
TCP ಅತ್ಯಂತ ಸಾಮಾನ್ಯ ಬಳಕೆಯ ಸಂದರ್ಭವಾಗಿದ್ದರೂ, ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್/ಪ್ರೋಟೋಕಾಲ್ ಮಾದರಿಯು ಅದಕ್ಕೆ ಸೀಮಿತವಾಗಿಲ್ಲ. Asyncio ಇತರ ಸಂವಹನ ಪ್ರಕಾರಗಳಿಗೆ ಅಮೂರ್ತತೆಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ:
- UDP: ಸಂಪರ್ಕವಿಲ್ಲದ ಸಂವಹನಕ್ಕಾಗಿ, ನೀವು
loop.create_datagram_endpoint()
ಅನ್ನು ಬಳಸುತ್ತೀರಿ. ಇದು ನಿಮಗೆDatagramTransport
ಅನ್ನು ನೀಡುತ್ತದೆ ಮತ್ತು ನೀವುdatagram_received(data, addr)
ಮತ್ತುerror_received(exc)
ನಂತಹ ವಿಧಾನಗಳೊಂದಿಗೆasyncio.DatagramProtocol
ಅನ್ನು ಅಳವಡಿಸುತ್ತೀರಿ. - SSL/TLS: ಎನ್ಕ್ರಿಪ್ಶನ್ ಸೇರಿಸುವುದು ನಂಬಲಾಗದಷ್ಟು ನೇರವಾಗಿರುತ್ತದೆ. ನೀವು
ssl.SSLContext
ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನುloop.create_server()
ಅಥವಾloop.create_connection()
ಗೆ ರವಾನಿಸುತ್ತೀರಿ. Asyncio TLS ಹ್ಯಾಂಡ್ಶೇಕ್ ಅನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿರ್ವಹಿಸುತ್ತದೆ, ಮತ್ತು ನೀವು ಸುರಕ್ಷಿತ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಅನ್ನು ಪಡೆಯುತ್ತೀರಿ. ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ ಕೋಡ್ ಅನ್ನು ಬದಲಾಯಿಸುವ ಅಗತ್ಯವಿಲ್ಲ. - ಉಪ-ಪ್ರಕ್ರಿಯೆಗಳು: ಚೈಲ್ಡ್ ಪ್ರಕ್ರಿಯೆಗಳೊಂದಿಗೆ ಅವುಗಳ ಪ್ರಮಾಣಿತ I/O ಪೈಪ್ಗಳ ಮೂಲಕ ಸಂವಹನ ನಡೆಸಲು,
asyncio.SubprocessProtocol
ನೊಂದಿಗೆloop.subprocess_exec()
ಮತ್ತುloop.subprocess_shell()
ಅನ್ನು ಬಳಸಬಹುದು. ಇದು ಸಂಪೂರ್ಣ ಅಸಮಕಾಲಿಕ, ನಾನ್-ಬ್ಲಾಕಿಂಗ್ ರೀತಿಯಲ್ಲಿ ಚೈಲ್ಡ್ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ನಿರ್ವಹಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ.
ಕಾರ್ಯತಂತ್ರದ ನಿರ್ಧಾರ: ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು vs. ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಯಾವಾಗ ಬಳಸಬೇಕು
ನಿಮ್ಮ ಇತ್ಯರ್ಥದಲ್ಲಿ ಎರಡು ಶಕ್ತಿಶಾಲಿ API ಗಳೊಂದಿಗೆ, ಸರಿಯಾದದನ್ನು ಆಯ್ಕೆ ಮಾಡುವುದು ಒಂದು ಪ್ರಮುಖ ವಾಸ್ತುಶಿಲ್ಪದ ನಿರ್ಧಾರವಾಗಿದೆ. ನಿರ್ಧರಿಸಲು ನಿಮಗೆ ಸಹಾಯ ಮಾಡಲು ಇಲ್ಲಿ ಒಂದು ಮಾರ್ಗದರ್ಶಿ ಇದೆ.
ಸ್ಟ್ರೀಮ್ಗಳನ್ನು (StreamReader
/StreamWriter
) ಆರಿಸಿಕೊಳ್ಳಿ ಯಾವಾಗ...
- ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ ಸರಳವಾಗಿದೆ ಮತ್ತು ವಿನಂತಿ-ಪ್ರತಿಕ್ರಿಯೆ ಆಧಾರಿತವಾಗಿದೆ. ತರ್ಕವು "ವಿನಂತಿಯನ್ನು ಓದು, ಅದನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸು, ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಬರೆ" ಆಗಿದ್ದರೆ, ಸ್ಟ್ರೀಮ್ಗಳು ಸೂಕ್ತವಾಗಿವೆ.
- ನೀವು ಸುಪರಿಚಿತ, ಸಾಲು ಆಧಾರಿತ ಅಥವಾ ಸ್ಥಿರ-ಉದ್ದದ ಸಂದೇಶ ಪ್ರೋಟೋಕಾಲ್ಗಾಗಿ ಕ್ಲೈಂಟ್ ಅನ್ನು ನಿರ್ಮಿಸುತ್ತಿದ್ದೀರಿ. ಉದಾಹರಣೆಗೆ, ರೆಡಿಸ್ ಸರ್ವರ್ ಅಥವಾ ಸರಳ FTP ಸರ್ವರ್ನೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸುವುದು.
- ನೀವು ಕೋಡ್ನ ಓದುವಿಕೆ ಮತ್ತು ರೇಖೀಯ, ಅನಿವಾರ್ಯ ಶೈಲಿಗೆ ಆದ್ಯತೆ ನೀಡುತ್ತೀರಿ. ಸ್ಟ್ರೀಮ್ಗಳೊಂದಿಗೆ
async/await
ಸಿಂಟ್ಯಾಕ್ಸ್ ಅಸಮಕಾಲಿಕ ಪ್ರೋಗ್ರಾಮಿಂಗ್ಗೆ ಹೊಸ ಡೆವಲಪರ್ಗಳಿಗೆ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಸಾಮಾನ್ಯವಾಗಿ ಸುಲಭವಾಗಿದೆ. - ವೇಗದ ಮೂಲಮಾದರಿಯು ಮುಖ್ಯವಾಗಿದೆ. ನೀವು ಕೆಲವೇ ಸಾಲುಗಳ ಕೋಡ್ನೊಂದಿಗೆ ಸ್ಟ್ರೀಮ್ಗಳೊಂದಿಗೆ ಸರಳ ಕ್ಲೈಂಟ್ ಅಥವಾ ಸರ್ವರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು.
ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳನ್ನು ಆರಿಸಿಕೊಳ್ಳಿ ಯಾವಾಗ...
- ನೀವು ಮೊದಲಿನಿಂದಲೂ ಸಂಕೀರ್ಣ ಅಥವಾ ಕಸ್ಟಮ್ ನೆಟ್ವರ್ಕ್ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಅಳವಡಿಸುತ್ತಿದ್ದೀರಿ. ಇದು ಪ್ರಾಥಮಿಕ ಬಳಕೆಯ ಸಂದರ್ಭವಾಗಿದೆ. ಗೇಮಿಂಗ್, ಹಣಕಾಸು ಡೇಟಾ ಫೀಡ್ಗಳು, IoT ಸಾಧನಗಳು ಅಥವಾ ಪೀರ್-ಟು-ಪೀರ್ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ ಪ್ರೋಟೋಕಾಲ್ಗಳ ಬಗ್ಗೆ ಯೋಚಿಸಿ.
- ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ ಹೆಚ್ಚು ಈವೆಂಟ್-ಚಾಲಿತವಾಗಿದೆ ಮತ್ತು ಸಂಪೂರ್ಣವಾಗಿ ವಿನಂತಿ-ಪ್ರತಿಕ್ರಿಯೆ ಆಧಾರಿತವಲ್ಲ. ಸರ್ವರ್ ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಕ್ಲೈಂಟ್ಗೆ ಅನಗತ್ಯ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದಾದರೆ, ಪ್ರೋಟೋಕಾಲ್ಗಳ ಕಾಲ್ಬ್ಯಾಕ್ ಆಧಾರಿತ ಸ್ವರೂಪವು ಹೆಚ್ಚು ನೈಸರ್ಗಿಕವಾಗಿ ಹೊಂದಿಕೊಳ್ಳುತ್ತದೆ.
- ನಿಮಗೆ ಗರಿಷ್ಠ ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಕನಿಷ್ಠ ಓವರ್ಹೆಡ್ ಅಗತ್ಯವಿದೆ. ಪ್ರೋಟೋಕಾಲ್ಗಳು ನಿಮಗೆ ಈವೆಂಟ್ ಲೂಪ್ಗೆ ಹೆಚ್ಚು ನೇರವಾದ ಮಾರ್ಗವನ್ನು ನೀಡುತ್ತವೆ, ಸ್ಟ್ರೀಮ್ಸ್ API ಗೆ ಸಂಬಂಧಿಸಿದ ಕೆಲವು ಓವರ್ಹೆಡ್ ಅನ್ನು ಬೈಪಾಸ್ ಮಾಡುತ್ತವೆ.
- ಸಂಪರ್ಕದ ಮೇಲೆ ನಿಮಗೆ ಉತ್ತಮ ನಿಯಂತ್ರಣದ ಅಗತ್ಯವಿದೆ. ಇದು ಹಸ್ತಚಾಲಿತ ಬಫರ್ ನಿರ್ವಹಣೆ, ಸ್ಪಷ್ಟ ಫ್ಲೋ ಕಂಟ್ರೋಲ್ (
pause/resume_writing
), ಮತ್ತು ಸಂಪರ್ಕ ಜೀವನಚಕ್ರದ ವಿವರವಾದ ನಿರ್ವಹಣೆಯನ್ನು ಒಳಗೊಂಡಿದೆ. - ನೀವು ನೆಟ್ವರ್ಕ್ ಫ್ರೇಮ್ವರ್ಕ್ ಅಥವಾ ಲೈಬ್ರರಿಯನ್ನು ನಿರ್ಮಿಸುತ್ತಿದ್ದೀರಿ. ನೀವು ಇತರ ಡೆವಲಪರ್ಗಳಿಗೆ ಒಂದು ಉಪಕರಣವನ್ನು ಒದಗಿಸುತ್ತಿದ್ದರೆ, ಪ್ರೋಟೋಕಾಲ್/ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ API ಯ ದೃಢವಾದ ಮತ್ತು ಹೊಂದಿಕೊಳ್ಳುವ ಸ್ವರೂಪವು ಸಾಮಾನ್ಯವಾಗಿ ಸರಿಯಾದ ಅಡಿಪಾಯವಾಗಿದೆ.
ತೀರ್ಮಾನ: ಅಸಿಂಕ್ಐಒದ ಅಡಿಪಾಯವನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳುವುದು
ಪೈಥಾನ್ನ asyncio
ಲೈಬ್ರರಿಯು ಲೇಯರ್ಡ್ ವಿನ್ಯಾಸದ ಒಂದು ಮೇರುಕೃತಿಯಾಗಿದೆ. ಉನ್ನತ-ಮಟ್ಟದ ಸ್ಟ್ರೀಮ್ಸ್ API ಒಂದು ಸುಲಭವಾಗಿ ಪ್ರವೇಶಿಸಬಹುದಾದ ಮತ್ತು ಉತ್ಪಾದಕ ಪ್ರವೇಶ ಬಿಂದುವನ್ನು ಒದಗಿಸಿದರೆ, ಅಸಿಂಕ್ಐಒದ ನೆಟ್ವರ್ಕಿಂಗ್ ಸಾಮರ್ಥ್ಯಗಳ ನಿಜವಾದ, ಶಕ್ತಿಶಾಲಿ ಅಡಿಪಾಯವನ್ನು ಪ್ರತಿನಿಧಿಸುವುದು ಲೋ-ಲೆವೆಲ್ ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ API. I/O ಕಾರ್ಯವಿಧಾನವನ್ನು (ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್) ಅಪ್ಲಿಕೇಶನ್ ತರ್ಕದಿಂದ (ಪ್ರೋಟೋಕಾಲ್) ಬೇರ್ಪಡಿಸುವ ಮೂಲಕ, ಇದು ಸಂಕೀರ್ಣ ನೆಟ್ವರ್ಕ್ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ದೃಢವಾದ, ಸ್ಕೇಲೆಬಲ್ ಮತ್ತು ನಂಬಲಾಗದಷ್ಟು ಹೊಂದಿಕೊಳ್ಳುವ ಮಾದರಿಯನ್ನು ಒದಗಿಸುತ್ತದೆ.
ಈ ಲೋ-ಲೆವೆಲ್ ಅಮೂರ್ತತೆಯನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ಕೇವಲ ಶೈಕ್ಷಣಿಕ ವ್ಯಾಯಾಮವಲ್ಲ; ಇದು ಸರಳ ಕ್ಲೈಂಟ್ಗಳು ಮತ್ತು ಸರ್ವರ್ಗಳನ್ನು ಮೀರಿ ಹೋಗಲು ನಿಮಗೆ ಅಧಿಕಾರ ನೀಡುವ ಪ್ರಾಯೋಗಿಕ ಕೌಶಲ್ಯವಾಗಿದೆ. ಇದು ಯಾವುದೇ ನೆಟ್ವರ್ಕ್ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ನಿಭಾಯಿಸಲು ನಿಮಗೆ ವಿಶ್ವಾಸವನ್ನು ನೀಡುತ್ತದೆ, ಒತ್ತಡದಲ್ಲಿ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಉತ್ತಮಗೊಳಿಸಲು ನಿಯಂತ್ರಣವನ್ನು ನೀಡುತ್ತದೆ ಮತ್ತು ಪೈಥಾನ್ನಲ್ಲಿ ಮುಂದಿನ ಪೀಳಿಗೆಯ ಉತ್ತಮ-ಕಾರ್ಯಕ್ಷಮತೆಯ, ಅಸಮಕಾಲಿಕ ಸೇವೆಗಳನ್ನು ನಿರ್ಮಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ನೀಡುತ್ತದೆ. ಮುಂದಿನ ಬಾರಿ ನೀವು ಸವಾಲಿನ ನೆಟ್ವರ್ಕಿಂಗ್ ಸಮಸ್ಯೆಯನ್ನು ಎದುರಿಸಿದಾಗ, ಮೇಲ್ಮೈ ಕೆಳಗೆ ಇರುವ ಶಕ್ತಿಯನ್ನು ನೆನಪಿಡಿ, ಮತ್ತು ಟ್ರಾನ್ಸ್ಪೋರ್ಟ್ಗಳು ಮತ್ತು ಪ್ರೋಟೋಕಾಲ್ಗಳ ಸೊಗಸಾದ ಜೋಡಿಯನ್ನು ತಲುಪಲು ಹಿಂಜರಿಯಬೇಡಿ.