التوسّع باستخدام Redis Backplane
وسّعوا SignalR عبر خوادم متعددة باستخدام Redis Backplane لمزامنة الرسائل بين النسخ.
التوسّع باستخدام Redis Backplane درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
مشكلة الخوادم المتعددة
عند تشغيل SignalR على خادم واحد، يتشارك العملاء والخادم الذاكرة الخاصة بالاتصالات والمجموعات. وعند التوسع إلى خادمين أو أكثر، لا يعرف كل خادم سوى اتصالاته هو — لذلك لا تصل رسالة تُرسل على الخادم A مطلقًا إلى العملاء المتصلين بالخادم B.
ما هو الناقل الخلفي؟
الناقل الخلفي هو ناقل رسائل مشترك بين مثيلات خوادم SignalR. فعندما يريد أحد الخوادم إرسال رسالة، ينشرها في الناقل الخلفي؛ فتستقبلها جميع الخوادم وتعيد توجيهها إلى اتصالاتها المحلية.
إضافة الناقل الخلفي Redis
ثبّتوا الحزمة Microsoft.AspNetCore.SignalR.StackExchangeRedis واستدعوا AddStackExchangeRedis() بعد AddSignalR().
// dotnet add package Microsoft.AspNetCore.SignalR.StackExchangeRedis
builder.Services.AddSignalR()
.AddStackExchangeRedis("localhost:6379", options =>
{
options.Configuration.ChannelPrefix =
RedisChannel.Literal("myapp"); // namespace your channels
});
// Or from config:
// .AddStackExchangeRedis(builder.Configuration.GetConnectionString("Redis")!);آلية عمل Redis Pub/Sub مع SignalR
يشترك كل خادم SignalR في قنوات Redis. وعندما ينشر الخادم A رسالة لمجموعة أو مستخدم، يسلّمها Redis إلى جميع المشتركين (الخوادم B وC وغيرها)، ثم تعيد هذه الخوادم توجيهها إلى اتصالاتها المحلية.
// Server A: client sends message
// Hub on Server A calls:
await Clients.Group("room-42").ReceiveMessage(user, msg);
// Internally SignalR publishes to Redis:
// PUBLISH signalr/myapp/group/room-42 <serialized message>
// Redis delivers to Server B and C
// Both servers find connections in "room-42" and push to themخيارات الإعداد
اضبطوا اتصال Redis بدقة لبيئة الإنتاج: TLS وكلمة المرور ومرونة الاتصال وبادئة قناة pub/sub.
builder.Services.AddSignalR()
.AddStackExchangeRedis(opts =>
{
opts.Configuration = ConfigurationOptions.Parse(
builder.Configuration["Redis:ConnectionString"]!);
opts.Configuration.Password = builder.Configuration["Redis:Password"];
opts.Configuration.Ssl = true;
opts.Configuration.AbortOnConnectFail = false;
opts.Configuration.ConnectRetry = 3;
});Azure SignalR Service
للتوسع المُدار بالكامل، استخدموا Azure SignalR Service. فهو يعمل بوصفه الناقل الخلفي ومدير الاتصالات — وتصبح خوادم التطبيق عديمة الحالة ولا تحتفظ باتصالات WebSocket بنفسها.
// dotnet add package Microsoft.Azure.SignalR
builder.Services.AddSignalR()
.AddAzureSignalR(builder.Configuration["Azure:SignalR:ConnectionString"]!);
// That's it — Azure manages all connections and backplane
// Your server scales to zero when not neededالجلسات الثابتة (حل بديل لعمليات النقل غير المعتمدة على WebSocket)
عند استخدام Server-Sent Events أو Long Polling (وليس WebSockets)، يجب أن يصل العميل نفسه دائمًا إلى الخادم نفسه — ويُطلق على ذلك اسم الجلسات الثابتة. اضبطوا ذلك في موازن التحميل أو الوكيل العكسي.
# Nginx: sticky session config (IP hash)
upstream signalr_servers {
ip_hash; # ensures same client hits same server
server server1:5000;
server server2:5000;
server server3:5000;
}
# Or use cookie-based sticky sessions:
# sticky cookie srv_id expires=1h;
# WebSockets don't need sticky sessions —
# the connection is long-lived on one serverالمجموعات عبر خوادم متعددة
يحافظ الناقل الخلفي على عضوية المجموعات. فإضافة اتصال إلى مجموعة على الخادم A تعني أن الخادم B يعرف به عبر Redis — وكل ذلك شفاف بالنسبة إلى كود التطبيق.
// This works correctly across servers:
public async Task JoinRoom(string room)
{
// Adds to Redis-backed group
await Groups.AddToGroupAsync(Context.ConnectionId, room);
// Clients.Group sends via Redis to all servers
await Clients.Group(room).UserJoined(Context.User!.Identity!.Name!);
}
// No code changes needed — the Redis backplane handles distributionمراقبة Redis Pub/Sub
راقبوا قنوات Redis للتحقق من حركة SignalR وتشخيص المشكلات. استخدموا redis-cli SUBSCRIBE أو Redis Insights لمراقبة تدفق الرسائل.
# redis-cli: monitor all SignalR channels
redis-cli PSUBSCRIBE "myapp*"
# Check active channel subscribers
redis-cli PUBSUB CHANNELS "myapp*"
# Check number of subscribers per channel
redis-cli PUBSUB NUMSUB "myapp/all"معالجة أعطال Redis
إذا أصبح Redis غير متاح، يعود SignalR إلى وضع التشغيل المحلي فقط — ولن تعبر الرسائل بين الخوادم. اضبطوا سياسات إعادة المحاولة والتنبيهات الخاصة باتصال Redis.
builder.Services.AddSignalR()
.AddStackExchangeRedis(opts =>
{
opts.Configuration = ConfigurationOptions.Parse(redisConn);
opts.Configuration.AbortOnConnectFail = false; // don't crash app
opts.Configuration.ConnectRetry = 5;
opts.Configuration.ReconnectRetryPolicy =
new ExponentialRetry(5000, maxDeltaBackoffMilliseconds: 60000);
});من الواقع العملي: بنية دردشة قابلة للتوسع
في بيئة الإنتاج، شغّلوا 3 مثيلات أو أكثر من خوادم SignalR خلف موازن تحميل، مع Redis (أو Azure SignalR Service) بوصفه الناقل الخلفي. وتوجد كل الحالة في Redis؛ أما الخوادم فعديمة الحالة ويمكن التخلص منها.
// Architecture:
// [Browser] -> [Load Balancer (any server, WebSocket)] ->
// [SignalR Server 1] -+
// [SignalR Server 2] -+-> [Redis Pub/Sub] -> all servers
// [SignalR Server 3] -+
// Server code is identical on all instances:
builder.Services.AddSignalR().AddStackExchangeRedis(redisConn);
app.MapHub<ChatHub>("/hubs/chat");
// Scale replicas: kubectl scale deployment chat --replicas=3تحقق سريع
ما المشكلة التي يحلها الناقل الخلفي لـ SignalR؟
مراجعة: التوسع باستخدام ناقل Redis الخلفي
أهم النقاط:
- من دون ناقل خلفي، لا تصل الرسائل من أحد الخوادم إلى العملاء الموجودين على خوادم أخرى
- تضيف AddStackExchangeRedis() ناقل Redis الخلفي القائم على pub/sub بشفافية
- يوفر Azure SignalR Service بديلًا مُدارًا بالكامل للناقل الخلفي ولا يتطلب خوادم
- تتطلب عمليات النقل غير المعتمدة على WebSocket (SSE وLong Polling) جلسات ثابتة
- تُزامَن عضوية المجموعات بين الخوادم عبر الناقل الخلفي
- اضبطوا AbortOnConnectFail=false وسياسات إعادة المحاولة لزيادة مرونة Redis
تعلم C# مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 93
- الدروس
- 346
الأسئلة الشائعة
هل درس «التوسّع باستخدام Redis Backplane» مجاني؟
نعم — نص درس «التوسّع باستخدام Redis Backplane» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «التوسّع باستخدام Redis Backplane»؟
وسّعوا SignalR عبر خوادم متعددة باستخدام Redis Backplane لمزامنة الرسائل بين النسخ. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «التوسّع باستخدام Redis Backplane»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مراكز SignalR والاتصالات
- المجموعات والمستخدمون وإدارة الاتصالات
- المراكز محدّدة الأنواع
- التوسّع باستخدام Redis Backplane