WebSocket على C#: إنشاء تطبيقات الوقت الفعلي في .NET

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

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

ابدأ الدورة

WebSocket على C#: إنشاء تطبيقات الوقت الفعلي في .NET

تتطلب تطبيقات الويب الحديثة بشكل متزايد نقلًا فوريًا للبيانات بين العميل والخادم. بروتوكول HTTP التقليدي، الذي يعمل وفق نموذج "طلب-استجابة"، ليس دائمًا فعالًا للمهام التي تهم فيها سرعة وتواتر التحديثات — مثل الدردشات، الألعاب عبر الإنترنت، أسعار الأسهم، وأنظمة المراقبة. هنا يأتي دور بروتوكول WebSocket، الذي ينشئ اتصالًا ثنائي الاتجاه دائمًا. في هذه المقالة، سنشرح بالتفصيل كيفية تنفيذ WebSocket باستخدام C# (.NET)، وسننشئ خادمًا وعميلًا متكاملين، بالإضافة إلى استعراض أفضل الممارسات.



ما هو WebSocket ولماذا هو مطلوب في .NET؟

WebSocket هو بروتوكول يعمل فوق TCP، ويوفر اتصالًا كامل الازدواجية. بعد إنشاء الاتصال عبر مصافحة HTTP (handshake)، يمكن نقل البيانات في كلا الاتجاهين دون تكاليف إضافية. على عكس Long Polling أو Server-Sent Events، يوفر WebSocket زمن انتقال ضئيل وحركة مرور منخفضة.

في نظام .NET البيئي، هناك طريقتان رئيسيتان للعمل مع الوقت الفعلي:

  • WebSocket الأصلي (System.Net.WebSockets) — واجهة برمجة تطبيقات منخفضة المستوى، متوفرة في ASP.NET Core. يمنح تحكمًا كاملاً في الاتصال، ومناسب للبروتوكولات المخصصة.
  • SignalR — مكتبة عالية المستوى من Microsoft، تقوم بتجريد WebSocket وتختار تلقائيًا وسيلة النقل (WebSocket, SSE, Long Polling). مثالية للمهام النموذجية (الدردشات، الإشعارات).

يعتمد الاختيار على المهمة: إذا كنت بحاجة إلى أقصى تحكم وأداء — استخدم WebSocket الأصلي؛ إذا كانت سرعة التطوير والبساطة هي الأولوية — استخدم SignalR.



إنشاء خادم WebSocket بلغة C# (ASP.NET Core)

لنستعرض تنفيذ الخادم خطوة بخطوة. للبدء، سننشئ مشروع ASP.NET Core (قالب فارغ أو Web API).



الخطوة 1: إعداد Middleware

أضف دعم WebSocket في طريقة Configure للملف Program.cs:

var builder = WebApplication.CreateBuilder(args);var app = builder.Build();

app.UseWebSockets(); // تفعيل دعم WebSocket

app.Map("/ws", async (HttpContext context) =>{ if (context.WebSockets.IsWebSocketRequest) { using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); await HandleWebSocketConnection(webSocket); } else { context.Response.StatusCode = 400; }});

app.Run();

async Task HandleWebSocketConnection(WebSocket webSocket){ var buffer = new byte[1024 * 4]; while (webSocket.State == WebSocketState.Open) { var result = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None);

if (result.MessageType == WebSocketMessageType.Close) { await webSocket.CloseAsync( WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); } else if (result.MessageType == WebSocketMessageType.Text) { var message = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.WriteLine($"تم الاستلام: {message}");

// رد الصدى var response = Encoding.UTF8.GetBytes($"صدى: {message}"); await webSocket.SendAsync( new ArraySegment<byte>(response), WebSocketMessageType.Text, true, CancellationToken.None); } }}

يقوم هذا الكود بإنشاء خادم صدى: يستقبل الرسائل النصية ويعيد إرسالها مع البادئة "صدى:". لاحظ إدارة حالة الاتصال ومعالجة الإغلاق.



الخطوة 2: إدارة الاتصالات المتعددة

في التطبيق الحقيقي، تحتاج إلى تخزين قائمة الاتصالات النشطة. استخدم ConcurrentDictionary أو ConcurrentBag:

public class WebSoc                

المدونات

توصيات الكتب