ما هو Tokio ولماذا نحتاجه؟
\n\nTokio هو بيئة تشغيل غير متزامنة (async runtime) للغة البرمجة Rust. يوفر البنية التحتية لكتابة تطبيقات شبكية سريعة وموثوقة وقابلة للتوسع. إذا كنت تكتب في Rust شيئًا يتعامل مع الشبكة أو الملفات أو يتطلب معالجة متوازية للطلبات دون حظر الخيوط، فأنت بحاجة إلى Tokio.
\n\nعلى عكس النهج التقليدي متعدد الخيوط، حيث تتم معالجة كل طلب في خيط نظام تشغيل منفصل (وهو مكلف ومحدود)، يستخدم Tokio نموذج الإدخال/الإخراج غير المتزامن القائم على الأحداث. يمكن لخيط واحد معالجة آلاف الاتصالات المفتوحة في وقت واحد، والتبديل بين المهام فقط عندما تنتظر المهمة الحالية (مثل القراءة من مقبس).
\n\nTokio ليس مجرد مكتبة، بل هو نظام بيئي. يتضمن:
\n- \n
- بيئة التشغيل — جدولة المهام ومشغلات الأحداث (epoll/kqueue/IOCP) \n
- بروتوكولات الشبكة القياسية — TCP, UDP, Unix sockets \n
- المؤقتات — sleep, interval, deadline \n
- المزامنة — كائنات المزامنة (mutexes)، الإشارات (semaphores)، الحواجز (barriers) للكود غير المتزامن \n
- الإدخال/الإخراج للملفات — القراءة/الكتابة غير المتزامنة للملفات \n
- الأدوات المساعدة — القنوات (mpsc, oneshot, broadcast)، المخازن المؤقتة، برامج الترميز \n
Tokio هو الأساس لمشاريع معروفة مثل إطار الويب Axum، وعميل HTTP Reqwest، ومآخذ الويب Tungstenite، وقواعد البيانات SQLx وغيرها الكثير.
\n\nالتثبيت
\n\nعلى عكس Python (pip) أو Node.js (npm)، يستخدم Rust نظام الحزم Cargo. لتثبيت Tokio، أضف التبعية إلى ملف Cargo.toml:
[dependencies]\ntokio = { version = "1", features = ["full"] }\n\nالعلامة features = ["full"] تُفعّل جميع إمكانيات Tokio. بالنسبة للمشاريع الإنتاجية، يُنصح باختيار الميزات المطلوبة فقط لتقليل وقت التجميع وحجم الملف الثنائي:
[dependencies]\ntokio = { version = "1", features = ["rt", "macros", "net", "io-util", "time", "sync"] }\n\nالميزات الرئيسية:
\n- \n
rt— بيئة تشغيل متعددة الخيوط \n macros— وحدات الماكرو#[tokio::main]وtokio::select!\n net— TCP, UDP, Unix sockets \n io-util— Reader/Writer غير متزامنين \n time— المؤقتات و sleep \n sync— بدائيات المزامنة \n fs— العمل غير المتزامن مع نظام الملفات \n process— تشغيل الأوامر غير المتزامن \n signal— معالجة إشارات نظام التشغيل \n
بداية سريعة
\n\nلنقم بإنشاء خادم HTTP بسيط يرد بـ "Hello, World!" على أي طلب. للقيام بذلك، سنحتاج أيضًا إلى crate hyper (مكتبة HTTP فوق Tokio):
// Cargo.toml\n// [dependencies]\n// tokio = { version = "1", features = ["full"] }\n// hyper = { version = "1", features = ["server", "http1"] }\n\nuse hyper::service::service_fn;\nuse hyper::{Request, Response, Server};\nuse hyper::body::Incoming;\nuse std::convert::Infallible;\n\nasync fn handle_request(_req: Request<Incoming>) -> Result<Response<String>, Infallible> {\n Ok(Response::new("Hello, World!".to_string()))\n}\n\n#[tokio::main]\nasync fn main() {\n let addr = ([127, 0, 0, 1], 3000).into();\n let server = Server::bind(&addr).serve(service_fn(handle_request));\n println!("Server running on http://{}", addr);\n if let Err(e) = server.await {\n eprintln!("Server error: {}", e);\n }\n}\n\nقم بتشغيل cargo run وافتح http://127.0.0.1:3000 في المتصفح. سترى "Hello, World!".