WebSocket على C#: تطبيقات الوقت الفعلي المتقدمة

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

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

ابدأ الدورة

مقدمة: لماذا WebSocket على C# هو اختيار المحترفين

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

في هذه المقالة، سنستعرض الجوانب المتقدمة للعمل مع WebSocket في C#. ستتعلم كيفية بناء خادم متسامح مع الأخطاء، وإدارة آلاف الاتصالات المتزامنة، ومعالجة الأخطاء، ودمج WebSocket مع الأطر الشائعة. المادة موجهة للمطورين الملمين بالفعل بأساسيات .NET والبرمجة غير المتزامنة.



هندسة خادم WebSocket المتقدم على C#

غالبًا ما يقتصر المثال الأساسي لخادم WebSocket في C# على معالج واحد. تتطلب حلول الإنتاج بنية مدروسة. دعنا نستعرض المكونات الرئيسية.



إدارة الاتصالات وتحديد هوية العملاء

بدلاً من قائمة بسيطة من الاتصالات، استخدم ConcurrentDictionary للتخزين الآمن للخيوط. يتم تعيين معرف فريد (GUID) لكل عميل وتخزين البيانات الوصفية (مثل اسم المستخدم، المجموعة).

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

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

public async Task RemoveConnection(string id) { if (_connections.TryRemove(id, out var socket) && socket.State == WebSocketState.Open) { await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed", CancellationToken.None); } _users.TryRemove(id, out _); }

public WebSocket? GetSocketById(string id) => _connections.GetValueOrDefault(id);}

يسمح هذا الأسلوب بإرسال الرسائل بسهولة إلى مستخدمين محددين أو مجموعات أو للجميع في وقت واحد.



معالجة الرسائل المجزأة

في التطبيقات الحقيقية، قد تصل البيانات في أجزاء. الطريقة القياسية ReceiveAsync تُرجع جزءًا واحدًا. لتجميع الرسالة الكاملة، استخدم حلقة:

public async Task<byte[]> ReceiveFullMessageAsync(WebSocket socket, CancellationToken ct){    using var ms = new MemoryStream();    WebSocketReceiveResult result;    var buffer = new byte[1024 * 4]; // 4KB مخزن مؤقت

do { result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), ct); ms.Write(buffer, 0, result.Count); } while (!result.EndOfMessage);

return ms.ToArray();}

هذا أمر بالغ الأهمية لنقل كائنات JSON الكبيرة أو البيانات الثنائية (الصور، الملفات).



التوسع: SignalR مقابل Raw WebSocket

بالنسبة للتطبيقات المعقدة، يطرح السؤال حول الاختيار بين WebSocket منخفض المستوى وSignalR - مكتبة من Microsoft تُجرد WebSocket. دعنا نستعرض السيناريوهات.



متى تستخدم Raw WebSocket

  • أقصى أداء وأقل عبء إضافي.
  • بروتوكول نقل مخصص (بيانات ثنائية، إطارات مخصصة).
  • التكامل مع عملاء غير .NET (مثل Go أو Rust).
  • التحكم الكامل في إدارة الاتصالات.


متى تختار SignalR

  • التوسع التلقائي عبر Redis Backplane أو Azure SignalR Service.
  • دعم وسائل النقل البديلة (Long Polling، Server-Sent

المدونات

توصيات الكتب