WebSocket على C#: تطبيقات الوقت الفعلي من الألف إلى الياء

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

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

ابدأ الدورة

مقدمة: لماذا WebSocket هو المعيار لتطبيقات الوقت الفعلي؟



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



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



أساسيات WebSocket في .NET: جانب الخادم



توفر منصة .NET دعماً مدمجاً لـ WebSocket من خلال مساحة الأسماء System.Net.WebSockets. دعنا ننظر في إنشاء خادم يعتمد على ASP.NET Core.



1. إعداد Middleware لـ WebSocket



للبدء، يجب إضافة دعم WebSocket إلى خط أنابيب معالجة الطلبات. في ملف 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 Echo(webSocket); } else { context.Response.StatusCode = 400; }});

app.Run("http://localhost:5000");

async Task Echo(WebSocket webSocket){ var buffer = new byte[1024 * 4]; var receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None);

while (!receiveResult.CloseStatus.HasValue) { // إرسال البيانات المستلمة مرة أخرى إلى العميل (صدى) await webSocket.SendAsync( new ArraySegment<byte>(buffer, 0, receiveResult.Count), receiveResult.MessageType, receiveResult.EndOfMessage, CancellationToken.None);

receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None); }

await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None);}


يقوم هذا الكود بإنشاء خادم صدى: كل ما يرسله العميل يعاد إليه. لاحظ استخدام async/await - العمل مع WebSocket يكون دائماً غير متزامن.



2. إدارة اتصالات متعددة



في التطبيق الحقيقي، تحتاج إلى إدارة اتصالات متعددة. لننشئ مدير اتصالات بسيط:



public class WebSocketConnectionManager{    private readonly ConcurrentDictionary<string, WebSocket> _connections = new();

public string AddConnection(WebSocket socket) { var id = Guid.NewGuid().ToString(); _connections.TryAdd(id, socket); return id; }

public async Task BroadcastMessageAsync(string message) { var tasks = _connections.Values.Select(async socket => { if (socket.State == WebSocketState.Open) { var bytes = Encoding.UTF8.GetBytes(message); await socket.SendAsync( new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None); } }); await Task.WhenAll(tasks); }}


تسمح هذه الفئة بتخزين جميع الاتصالات النشطة وإرسال الرسائل

المدونات

توصيات الكتب