WebSocket في C++: تطبيقات الوقت الفعلي المتقدمة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

WebSocket على C++: إنشاء تطبيقات عالية الأداء في الوقت الفعلي



في عالم تطوير الويب الحديث، أصبح التفاعل في الوقت الفعلي معيارًا فعليًا للمنصات المالية والألعاب عبر الإنترنت وأنظمة المراقبة والدردشات. إذا كنت بحاجة إلى أقصى أداء وأقل تأخير، تظل لغة C++ الخيار الوحيد. في هذه المقالة، سنستعرض تقنيات متقدمة للعمل مع WebSocket بلغة C++، تتجاوز حدود خادم echo البسيط.



سنركز على الحلول المعمارية التي تتيح معالجة عشرات الآلاف من الاتصالات المتزامنة، وسنحلل أمثلة محددة من الكود باستخدام المكتبات الشائعة.



1. اختيار المكتبة وإعداد المشروع



لتطوير الإنتاج بلغة C++، هناك نهجان رئيسيان: استخدام المكتبة عالية المستوى uWebSockets (uWS) أو المجموعة منخفضة المستوى Boost.Asio + Boost.Beast. الخيار الأول أبسط، بينما الثاني يمنحك تحكمًا كاملاً.



Boost.Beast (المبني على Asio) هو المعيار الصناعي للمشاريع التي تكون فيها كل ميكروثانية مهمة. دعنا نستعرض الهيكل الأساسي لخادم WebSocket غير المتزامن:



#include <boost/beast/core.hpp>#include <boost/beast/websocket.hpp>#include <boost/asio.hpp>#include <memory>#include <string>

namespace beast = boost::beast;namespace websocket = beast::websocket;namespace net = boost::asio;using tcp = net::ip::tcp;

// فئة لمعالجة اتصال واحدclass WebSocketSession : public std::enable_shared_from_this<WebSocketSession> { websocket::stream<beast::tcp_stream> ws_; beast::flat_buffer buffer_;public: explicit WebSocketSession(tcp::socket&& socket) : ws_(std::move(socket)) {}

void run() { // قبول WebSocket handshake بشكل غير متزامن ws_.async_accept( beast::bind_front_handler(&WebSocketSession::on_accept, shared_from_this())); }

void on_accept(beast::error_code ec) { if(!ec) { // إرسال رسالة ترحيبية ws_.async_write( net::buffer(std::string("مرحبًا بك في عالم الوقت الفعلي!")), beast::bind_front_handler(&WebSocketSession::on_write, shared_from_this())); do_read(); } } // ... (يتبع أدناه)};


النقطة الأساسية: يحصل كل عميل على مثيل خاص به من WebSocketSession يعمل في وضع غير متزامن. هذا يسمح بعدم حظر الخيط الرئيسي أثناء انتظار البيانات.



2. بنية الخادم متعدد الخيوط مع تجمع الخيوط



يصل الخيط الواحد io_context إلى حد وحدة المعالجة المركزية. للتوسع إلى آلاف الاتصالات، استخدم تجمع الخيوط. يقوم كل خيط بتشغيل مثيله الخاص من io_context، ويتم توزيع الاتصالات عبر موازنة القبول.



void run_server(const std::string& address, unsigned short port, int thread_count) {    net::io_context ioc{thread_count}; // إنشاء io_context مع تحديد عدد الخيوط

tcp::acceptor acceptor{ioc, {net::ip::make_address(address), port}};

// بدء القبول في حلقة std::function<void()> do_accept = [&]() { acceptor.async_accept( [&](beast::error_code ec, tcp::socket socket) { if (!ec) { // إنشاء جلسة وتمرير المقبس إليها std::make_shared<WebSocketSession>(std::move(socket))->run(); } do_accept(); // الاستمرار في القبول }); }; do_accept();

// تشغيل تجمع الخيوط std::vector<std::thread> threads; for (int i = 0; i < thread_count; ++i) { threads.emplace_back([&ioc]() { ioc.run(); }); }

for (auto& t : threads) t.join();}


مهم

المدونات

توصيات الكتب