أحداث مرسلة من الخادم في C#: ويب تفاعلي بدون WebSocket

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

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

ابدأ الدورة

لماذا لا يزال موقعك "يتحدث" مع المستخدم في الوقت الفعلي؟

\n\n

تخيل: تفتح محطة تداول، وسعر الدولار يتجدد تلقائياً. أو تدخل لوحة الإدارة - وترى عدد المستخدمين المسجلين يتزايد أمام عينيك. أو دردشة حيث تصل الرسائل دون تحديثات مستمرة للصفحة.

\n\n

في السابق، كان عليك إما استخدام WebSocket (معقد، مكلف، ليس ضرورياً دائماً) أو استخدام long polling (حل مؤقت يستهلك بطارية الهاتف). لكن هناك طريق ثالث - الأحداث المرسلة من الخادم في C#.

\n\n

اليوم سنشرح تقنية تسمح للخادم بـ"النقر" على العميل وإرسال البيانات. بدون كود زائد، بدون أطنان من JavaScript، بدون صداع مع خوادم الوكيل. فقط C#، فقط هاردكور.

\n\n

ما هي الأحداث المرسلة من الخادم (SSE) ولماذا ليست "بروتوكولاً للفقراء"

\n\n

الأحداث المرسلة من الخادم (أو SSE) هي معيار HTML5 يسمح للخادم بإرسال بيانات متدفقة إلى العميل عبر اتصال HTTP عادي. العميل يشترك في الأحداث، والخادم يكتب ببساطة في Response.Body. هذا كل شيء.

\n\n

الفرق الرئيسي عن WebSocket: SSE هي قناة أحادية الاتجاه (خادم ← عميل). لست بحاجة لإرسال البيانات مرة أخرى؟ ممتاز، SSE هو خيارك. مع ذلك:

\n\n
    \n
  • يعمل عبر HTTP/1.1 و HTTP/2 العاديين
  • \n
  • يعيد الاتصال تلقائياً عند الانقطاع (مدمج في EventSource في المتصفح)
  • \n
  • لا يتطلب مكتبات إضافية على العميل (باستثناء JavaScript القياسي)
  • \n
  • يمر عبر أي خوادم وكيل وموازنات تحميل (على عكس WebSocket)
  • \n
\n\n

عملياً، يُستخدم SSE C# من أجل:

\n
    \n
  • خلاصات الإشعارات (إشعارات دفع مباشرة إلى المتصفح)
  • \n
  • مراقبة الخوادم (لوحات معلومات بمقاييس حية)
  • \n
  • بث السجلات (مثل tail -f في المتصفح)
  • \n
  • تدفق توليدات الذكاء الاصطناعي (إخراج تدريجي من نماذج مشابهة لـ ChatGPT)
  • \n
\n\n

كيف يعمل SSE: بروتوكول في سطر واحد

\n\n

كل شيء عبقري بسيط. الخادم يرسل للعميل تدفقاً من النص بتنسيق خاص:

\n\n
data: مرحباً أيها العالم!\\n\\n\ndata: {"message": "JSON يعمل أيضاً"}\\n\\n\nevent: customEvent\\n\ndata: حدث باسم\\n\\n
\n\n

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

\n\n

العميل في JavaScript يشترك كالتالي:

\n\n
const source = new EventSource("/api/stream");\nsource.onmessage = (event) => {\n    console.log("تم الاستلام:", event.data);\n};\nsource.addEventListener("customEvent", (event) => {\n    console.log("حدث مخصص:", event.data);\n});
\n\n

وهذا يعمل في جميع المتصفحات الحديثة. لا حاجة لحزم npm، ولا حاجة لـ WebSocket polyfills.

\n\n

الأحداث المرسلة من الخادم في C#: التنفيذ على ASP.NET Core

\n\n

دعنا أخيراً نكتب الكود. أبسط طريقة لتنظيم SSE في C# هي نقطة نهاية (endpoint) في ASP.NET Core لا تنهي الاستجابة، بل تكتب فيها على أجزاء.

\n\n

نقطة نهاية SSE أساسية

\n\n
using Microsoft.AspNetCore.Mvc;\n\n[ApiController]\n[Route("api")]\npublic class StreamController : ControllerBase\n{\n    [HttpGet("stream")]\n    public async Task Get(CancellationToken cancellationToken)\n    {\n        Response.Headers.Append("Content-Type", "text/event-stream");\n        Response.Headers.Append("Cache-Control", "no-cache");\n        Response.Headers.Append("Connection", "keep-alive");\n\n        for (int i = 0; i < 10; i++)\n        {\n            if (cancellationToken.IsCancellationRequested)\n                break;\n\n            // تنسيق SSE: data: ... \\n\\n\n            await Response.WriteAsync($"data: رسالة #{i}\\n\\n",                

المدونات

توصيات الكتب