परिचय: Rust रीयल-टाइम के लिए आदर्श उम्मीदवार क्यों है?
\n\nएक स्थिति की कल्पना करें: आप Rust में एक चैट सर्वर, स्टॉक एक्सचेंज टर्मिनल या मॉनिटरिंग सिस्टम लिख रहे हैं। उपयोगकर्ता तुरंत अपडेट प्राप्त करना चाहते हैं। कोई भी मैन्युअल रूप से "रिफ्रेश" बटन दबाना पसंद नहीं करता - यह पुरानी बात है। लेकिन सर्वर से क्लाइंट तक डेटा डिलीवरी कैसे व्यवस्थित करें?
\n\nलंबे समय तक, एकमात्र तरीका long polling था - एक सुंदर, लेकिन थोड़ा "अस्थायी समाधान" वाला ट्रिक। फिर WebSocket आया और वेब डेवलपमेंट की दुनिया बदल गई। और अब हमारे पास Rust है - एक ऐसी भाषा जो मेमोरी सुरक्षा से समझौता किए बिना दोनों दृष्टिकोणों से अधिकतम लाभ उठाने की अनुमति देती है।
\n\nइस लेख में, हम केवल Rust में long polling और WebSocket की तुलना नहीं करेंगे - हम काम करने वाले उदाहरण लिखेंगे, उन्हें चलाएंगे और देखेंगे कि हुड के नीचे क्या होता है। यदि आप Rust पर रीयल-टाइम एप्लिकेशन लिख रहे हैं और तकनीक चुनने में संशय में हैं - तो आप सही जगह पर हैं।
\n\nLong Polling क्या है (सरल भाषा में)
\n\nLong polling एक तकनीक है जिसमें क्लाइंट सर्वर पर HTTP अनुरोध खोलता है और... प्रतीक्षा करता है। सर्वर तुरंत जवाब नहीं देता, बल्कि कनेक्शन को तब तक खुला रखता है जब तक कोई नई घटना न हो या टाइमआउट समाप्त न हो जाए।
\n\nकल्पना करें कि आप एक मित्र को फोन करते हैं और कहते हैं: "जब पार्सल आए तो मुझे कॉल करना" - और आप एक घंटे तक लाइन पर लटके रहते हैं। यह long polling है। सामान्य polling वह है जब आप हर 5 मिनट में वापस कॉल करते हैं: "क्या आ गया?"
\n\nActix-web के साथ Rust में Long Polling का कार्यान्वयन
\n\nआइए actix-web पर एक सरल सर्वर लिखें जो long polling का उपयोग करता है। हमारे पास एक संदेश कतार होगी - जब कोई नया संदेश आता है, तो सभी "प्रतीक्षारत" इसे प्राप्त करते हैं।
\n\nuse actix_web::{web, App, HttpServer, HttpRequest, HttpResponse};\nuse std::sync::Mutex;\nuse tokio::sync::broadcast;\n\nstruct AppState {\n tx: broadcast::Sender<String>,\n}\n\nasync fn long_poll_handler(data: web::Data<Mutex<AppState>>) -> HttpResponse {\n let mut rx = {\n let state = data.lock().unwrap();\n state.tx.subscribe()\n };\n\n // 30 सेकंड के लिए नए संदेश की प्रतीक्षा करें\n match tokio::time::timeout(\n std::time::Duration::from_secs(30),\n rx.recv()\n ).await {\n Ok(Ok(msg)) => HttpResponse::Ok().body(msg),\n Ok(Err(_)) => HttpResponse::InternalServerError().finish(),\n Err(_) => HttpResponse::NoContent().finish(), // टाइमआउट\n }\n}\n\n#[actix_web::main]\nasync fn main() -> std::io::Result<()> {\n let (tx, _) = broadcast::channel::<String>(100);\n\n HttpServer::new(move || {\n App::new()\n .app_data(web::Data::new(Mutex::new(AppState { tx: tx.clone() })))\n .route("/poll", web::get().to(long_poll_handler))\n })\n .bind("127.0.0.1:8080")?\n .run()\n .await\n}\n\nक्लाइंट बस GET /poll पर लटका रहेगा। जब कोई संदेश आएगा - सर्वर जवाब देगा। यदि 30 सेकंड में कुछ नहीं आता - तो 204 No Content लौटाएगा, और क्लाइंट फिर से अनुरोध करेगा।
लाभ:
\n- \n
- सामान्य HTTP के माध्यम से काम करता है - WebSocket समर्थन वाले प्रॉक्सी सर्वर की आवश्यकता नहीं \n
- मौजूदा REST API के साथ एकीकरण में आसानी \n
- कॉर्पोरेट नेटवर्क के लिए उपयुक्त जहां प्रॉक्सी WebSocket को ब्लॉक करते हैं \n
नुकसान:
\n- \n
- प्रत्येक "पोलिंग" एक कनेक्शन रखता है - 10,000 क्लाइंट पर यह 10,000 खुले TCP कनेक्शन होंगे \n
- विलंब: क्लाइंट टाइमआउट के बाद भी पुनः कनेक्ट होता है \n
- सर्वर "लटके" अनुरोधों को बनाए रखने के लिए संसाधन खर्च करता है \n
Rust में WebSocket: जब गति चाहिए
\n\nWebSocket अब "कॉल और प्रतीक्षा" नहीं है, बल्कि एक पूर्ण द्वि-दिशात्मक चैनल है। सर्वर और क्लाइंट बिना HTTP हेडर के ओवरहेड के किसी भी समय संदेशों का आदान-प्रदान कर सकते हैं।
\n\nRust में WebSocket इकोसिस्टम समृद्ध है: निम्न-स्तरीय कार्य के लिए tokio-tungstenite, actix-web अपने स्वयं के साथ