Long Polling مقابل WebSocket في C#: أيهما تختار للوقت الفعلي؟

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

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

ابدأ الدورة

اتصال طويل أم قناة دائمة: كيف ينقل C# البيانات في الوقت الفعلي

\n\n

تخيل: أنت تكتب تطبيق دردشة بلغة C#. أو محطة تداول. أو نظام إشعارات. العميل ينتظر البيانات - وهو غير مستعد للانتظار طويلاً. في السابق، كان المطورون يتدبرون أمرهم كما يستطيعون: يضعون مؤقتات، ويستدعون الخادم كل 5 ثوانٍ، ويولدون طلبات زائدة. اليوم لدينا نهجان متحضران - Long Polling و WebSocket. كلاهما يسمح للخادم بإرسال البيانات إلى العميل دون طلب صريح منه. لكنهما يعملان بشكل مختلف جوهريًا.

\n\n

في هذه المقالة، سنشرح كيفية تنفيذ كلا النهجين بلغة C# (ASP.NET Core)، ونقارنهما من حيث السرعة والحمل والتعقيد، ونفهم أيهما تختار لمشروعك. هيا بنا.

\n\n

ما هو Long Polling؟ (ولماذا ليس سحرًا)

\n\n

Long Polling هو محاكاة للوقت الفعلي عبر HTTP العادي. يرسل العميل طلبًا إلى الخادم، لكن الخادم لا يرد فورًا. يبقي الاتصال مفتوحًا حتى يظهر حدث جديد (أو ينتهي المهلة). بمجرد أن تصبح البيانات جاهزة - يرسل الخادم الرد، ويعالجه العميل ويفتح على الفور طلبًا "طويلاً" جديدًا.

\n\n

هذه خدعة ذكية تعمل على أي خادم HTTP وفي أي متصفح. لكن لها ثمن: كل اتصال يعلق في ذاكرة الخادم، وإذا كان لديك آلاف العملاء - فهذه مشكلة.

\n\n

مثال Long Polling بلغة C# (ASP.NET Core)

\n\n

لنكتب وحدة تحكم بسيطة تحاكي قائمة انتظار الإشعارات. يقوم العميل باستدعاء نقطة النهاية، وينتظر الخادم بيانات جديدة (على سبيل المثال، من قناة Channel<string>) ويرسلها.

\n\n
using Microsoft.AspNetCore.Mvc;\nusing System.Threading.Channels;\n\n[ApiController]\n[Route("api/[controller]")]\npublic class NotificationsController : ControllerBase\n{\n    private static readonly Channel<string> _channel = Channel.CreateUnbounded<string>();\n\n    // نقطة نهاية لنشر إشعار (على سبيل المثال، من خدمة أخرى)\n    [HttpPost("publish")]\n    public async Task<IActionResult> Publish([FromBody] string message)\n    {\n        await _channel.Writer.WriteAsync(message);\n        return Ok("تم إرسال الإشعار");\n    }\n\n    // Long Polling: العميل ينتظر حتى تظهر رسالة جديدة\n    [HttpGet("long-poll")]\n    public async Task<IActionResult> LongPoll(CancellationToken cancellationToken)\n    {\n        // انتظار رسالة جديدة؛ إذا لم يكن هناك شيء - انتظر حتى 30 ثانية\n        using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);\n        cts.CancelAfter(TimeSpan.FromSeconds(30));\n\n        try\n        {\n            var message = await _channel.Reader.ReadAsync(cts.Token);\n            return Ok(new { data = message });\n        }\n        catch (OperationCanceledException)\n        {\n            // انتهاء المهلة - نعيد ردًا فارغًا، وسيكرر العميل الطلب\n            return Ok(new { data = (string?)null });\n        }\n    }\n}\n
\n\n

العميل (JavaScript) سيبدو هكذا:

\n\n
async function startLongPoll() {\n    while (true) {\n        const response = await fetch('/api/notifications/long-poll');\n        const result = await response.json();\n        if (result.data) {\n            console.log('إشعار جديد:', result.data);\n        }\n        // نبدأ فورًا استقصاء جديدًا\n    }\n}\nstartLongPoll();\n
\n\n

كل شيء بسيط. لكن هناك فارق بسيط: إذا تمت إعادة تشغيل الخادم أو فقد العميل الاتصال - فستفقد البيانات. Long Polling لا يضمن التسليم.

\n\n

WebSocket: نفق ثنائي الاتجاه بلغة C#

\n\n

WebSocket هو بروتوكول كامل للاتصال ثنائي الاتجاه عبر TCP. بعد المصافحة (طلب HTTP GET عادي مع ترقية) يتواصل العميل والخادم مباشرة، دون تكاليف إضافية لرؤوس HTTP. يمكن للخادم إرسال رسالة في أي لحظة، وسيتلقاها العميل فورًا.

\n\n

في ASP.NET Core، WebSocket مدمج بشكل افتراضي. لا حاجة لمكتبات خارجية (

المدونات

توصيات الكتب