أحداث مرسلة من الخادم في C++: الوقت الفعلي بدون سحر ومكتبات إضافية

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

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

ابدأ الدورة

لماذا طلب HTTP العادي يشبه رسالة بريدية، بينما SSE يشبه برقية في الوقت الفعلي

\n\n

تخيل: أنت تنتظر إشعارًا بتعليق جديد على موقع. تقوم بتحديث الصفحة كل 5 ثوانٍ. في كل مرة، يعيد الخادم الكثير من HTML وCSS والصور - وفقط في النهاية ترى: "لا توجد تعليقات جديدة". مألوف؟ هذا يسمى polling. يعمل، لكنه يستهلك النطاق الترددي ويُثقل الخادم.

\n\n

والآن تخيل سيناريو آخر: فتحت الصفحة، وبعد ثانية تظهر عليها رسالة: "فاسيلي ترك تعليقًا: 'مقال رائع!'". بدون إعادة تحميل، بدون طلبات إضافية. الخادم نفسه "يدفع" لك البيانات. هذه هي الأحداث المرسلة من الخادم (SSE) - تقنية تسمح للخادم بإرسال تيار من الأحداث إلى العميل عبر اتصال HTTP عادي.

\n\n

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

\n\n

كيف تعمل الأحداث المرسلة من الخادم؟ تحليل البروتوكول

\n\n

SSE هي جزء من مواصفات HTML5. يفتح العميل اتصال HTTP عادي ويقول للخادم: "أنا مستعد لاستماع الأحداث". الخادم بدوره لا يغلق الاتصال، بل يبدأ بإرسال البيانات بتنسيق خاص text/event-stream.

\n\n

تنسيق الرسالة بسيط للغاية:

\n\n
data: هذا نص الحدث\\n\\n
\n\n

كل حدث يبدأ بـ data: وينتهي بسطر جديد مزدوج. يمكن إضافة id: للتعريف، و event: لنوع الحدث، و retry: لتحديد وقت إعادة الاتصال بالميلي ثانية.

\n\n

مثال لتيار كامل:

\n\n
id: 42\nevent: new_message\ndata: {"user": "فاسيلي", "text": "مرحبًا!"}\n\nid: 43\nevent: ping\ndata: الخادم حي\n\n
\n\n

يقوم العميل (المتصفح أو أي تطبيق) بمعالجة هذه الأسطر ويولد أحداث JavaScript. كل شيء عبقري بسيط.

\n\n

SSE مقابل WebSocket: متى تختار ماذا؟

\n\n

كثيرون يفكرون فورًا في WebSocket عندما يتعلق الأمر بالوقت الفعلي. دعنا نقارن:

\n\n
    \n
  • WebSocket - اتصال ثنائي الاتجاه. يمكن للعميل والخادم بدء التبادل. يتطلب بروتوكولًا منفصلاً (ws://)، وعبورًا عبر البروكسي، وغالبًا ما يتم حظره بواسطة جدران الحماية المؤسسية.
  • \n
  • SSE - اتصال أحادي الاتجاه (خادم → عميل). يعمل فوق HTTP العادي. يعيد الاتصال تلقائيًا عند الانقطاع. يمر بسهولة عبر أي بروكسي.
  • \n
\n\n

إذا كانت مهمتك هي إرسال إشعارات للعميل، وليس انتظار أوامر منه، فإن الأحداث المرسلة من الخادم في C++ هي حل أنيق وبسيط. لا حاجة لسحب مكتبات ثقيلة، ولا حاجة لكتابة معالجات معقدة.

\n\n

كتابة خادم SSE في C++ من الصفر

\n\n

للتطبيق، سنحتاج إلى الحد الأدنى: مآخذ توصيل (sockets) والعمل مع HTTP. في المشاريع الحقيقية، يستخدمون Boost.Beast أو libmicrohttpd، لكن لفهم الجوهر، سنكتب خادمًا بسيطًا بلغة C++ خالصة باستخدام POSIX sockets.

\n\n

سيكون خادمنا قادرًا على:

\n
    \n
  • استقبال طلب HTTP من العميل
  • \n
  • تحديد أن العميل يريد SSE (عن طريق الترويسة Accept: text/event-stream)
  • \n
  • إرسال تيار من الأحداث مع الوقت الحالي كل ثانيتين
  • \n
\n\n

الخطوة 1: إنشاء مأخذ توصيل والاستماع على المنفذ

\n\n
#include <iostream>\n#include <string>\n#include <cstring>\n#include <unistd.h>\n#include <arpa/inet.h>\n#include <sys/socket.h>\n#include <thread>\n#include <chrono>\n#include <sstream>\n\nvoid handle_client(int client_socket) {\n    // مخزن للطلب\n    char buffer[4096] = {0};\n    read(client_socket, buffer, 4096);\n    \n    // نتحقق مما إذا كان هذا طلب GET                

المدونات

توصيات الكتب