مقدمة: لماذا WebSocket و C++ ثنائي مثالي للتطبيقات اللحظية (real-time)
في عالم تطبيقات الويب الحديث، اعتاد المستخدمون على التحديثات الفورية: الإشعارات في شبكات التواصل الاجتماعي، الدردشات المباشرة (live-chats)، أسعار الأسهم، الألعاب عبر الإنترنت. النهج التقليدي باستخدام طلبات HTTP (Polling) يُحدث حملاً زائداً على الخادم ويزيد من زمن الاستجابة. الحل هو بروتوكول WebSocket، الذي يُنشئ اتصالاً دائماً ثنائي الاتجاه بين العميل والخادم.
لغة C++ مثالية لبناء أنظمة لحظية عالية التحميل بفضل أدائها العالي، التحكم منخفض المستوى في الذاكرة، والتكاليف الإضافية البسيطة. في هذه المقالة، سنشرح كيفية تنفيذ خادم وعميل WebSocket باستخدام C++ مع المكتبات الحديثة، وسنستعرض أفضل ممارسات التطوير.
أساسيات WebSocket واختيار الأدوات
كيف يعمل WebSocket؟
WebSocket هو بروتوكول يعمل فوق TCP، يبدأ بمصافحة HTTP (handshake)، ثم يتحول إلى وضع نقل البيانات الثنائي. بعد إنشاء الاتصال، يتم تبادل الرسائل بدون رؤوس إضافية، مما يسرّع النقل بشكل كبير.
الخصائص الرئيسية:
- اتصال كامل الازدواج (full-duplex) (يمكن للخادم والعميل إرسال البيانات في وقت واحد)
- زمن استجابة منخفض (latency)
- دعم الإطارات النصية والثنائية
- إدارة تلقائية للاتصال (ping/pong للإبقاء على الاتصال)
المكتبات الشائعة لـ WebSocket في C++
للعمل مع WebSocket في C++، توجد عدة حلول ناضجة:
- Boost.Beast — جزء من مكتبة Boost، مبني على ASIO. يوفر تحكماً كاملاً، مثالي للمشاريع الصناعية.
- uWebSockets (µWebSockets) — مكتبة خفيفة الوزن وعالية الأداء، تُستخدم غالباً مع Node.js أو كخادم مستقل.
- libwebsockets — مكتبة متعددة المنصات مع ميزات غنية (SSL, IPv6).
- IXWebSocket — سهلة الاستخدام، مناسبة للمشاريع الصغيرة والنماذج الأولية.
في هذه المقالة، سنركز على Boost.Beast باعتباره الحل الأكثر مرونة وقوة.
تنفيذ عملي لخادم WebSocket بلغة C++ باستخدام Boost.Beast
إعداد المشروع
في البداية، تأكد من تثبيت مترجم يدعم C++17 ومكتبة Boost (الإصدار 1.75+). التثبيت عبر مدير الحزم:
# Ubuntu/Debiansudo apt install libboost-all-dev# macOS (Homebrew)brew install boostإنشاء خادم WebSocket بسيط (echo server)
لننظر إلى مثال أساسي لخادم يستقبل الاتصالات ويعيد إرسال الرسائل المستلمة (echo).
#include <boost/beast/core.hpp>#include <boost/beast/websocket.hpp>#include <boost/asio/ip/tcp.hpp>#include <iostream>#include <string>#include <thread>
namespace beast = boost::beast;namespace websocket = beast::websocket;namespace net = boost::asio;using tcp = net::ip::tcp;
void do_session(tcp::socket& socket) { try { // إنشاء تيار WebSocket من المقبس websocket::stream<tcp::socket> ws{std::move(socket)}; // تنفيذ المصافحة ws.accept();
// حلقة معالجة الرسائل while (true) { beast::flat_buffer buffer; // قراءة رسالة من العميل ws.read(buffer); // إعادة إرسال الرسالة (echo) ws.text(ws.got_text()); // الحفاظ على نوع الرسالة ws.write(buffer.data()); // طباعة الرسالة المستلمة في وحدة التحكم std::cout << "Received: " << beast::make_printable(buffer.data()) << std::endl; } } catch (beast::system_error
```