UZMAN
SignalR Redis Backplane
Multi-instance SignalR uygulamalarını Redis Pub/Sub ile scale-out.
Kod örneği görünümü
Bu sayfadaki eşleşen örnekleri seçilen istemciye göre gösterir.
# SignalR otomatik channel'lar oluşturur:
PUBSUB CHANNELS "SignalR:*"
# SignalR:MyHub:All
# SignalR:MyHub:Group:admins
# SignalR:MyHub:User:user123
# SignalR:MyHub:Connection:conn-id
// NuGet: dotnet add package Microsoft.AspNetCore.SignalR.StackExchangeRedis
builder.Services.AddSignalR()
.AddStackExchangeRedis(builder.Configuration.GetConnectionString("Redis")!, options =>
{
options.Configuration.ChannelPrefix = RedisChannel.Literal("SignalR");
});
// Hub (değişiklik yok — Redis backplane şeffaf çalışır)
public class NotificationHub : Hub
{
public async Task SendToUser(string userId, string message)
{
await Clients.User(userId).SendAsync("ReceiveNotification", message);
}
public async Task SendToGroup(string group, string message)
{
await Clients.Group(group).SendAsync("ReceiveMessage", message);
}
public override async Task OnConnectedAsync()
{
var userId = Context.UserIdentifier;
if (userId is not null)
await Groups.AddToGroupAsync(Context.ConnectionId, $"user:{userId}");
await base.OnConnectedAsync();
}
}
// Controller'dan hub'a mesaj gönderme (herhangi bir instance'dan)
[ApiController]
[Route("api/[controller]")]
public class NotificationsController : ControllerBase
{
private readonly IHubContext<NotificationHub> _hubContext;
public NotificationsController(IHubContext<NotificationHub> hubContext)
=> _hubContext = hubContext;
[HttpPost("broadcast")]
public async Task<IActionResult> Broadcast([FromBody] string message)
{
// Bu mesaj Redis üzerinden TÜM instance'lardaki client'lara ulaşır
await _hubContext.Clients.All.SendAsync("ReceiveNotification", message);
return Ok();
}
[HttpPost("user/{userId}")]
public async Task<IActionResult> SendToUser(string userId, [FromBody] string message)
{
await _hubContext.Clients.User(userId).SendAsync("ReceiveNotification", message);
return Ok();
}
}
# docker-compose.yml — 3 instance SignalR + Redis + nginx
services:
redis:
image: redis:8-alpine
ports: ["6379:6379"]
api-1:
build: .
environment:
- ConnectionStrings__Redis=redis:6379
- ASPNETCORE_URLS=http://+:5000
api-2:
build: .
environment:
- ConnectionStrings__Redis=redis:6379
- ASPNETCORE_URLS=http://+:5000
api-3:
build: .
environment:
- ConnectionStrings__Redis=redis:6379
- ASPNETCORE_URLS=http://+:5000
nginx:
image: nginx:alpine
ports: ["80:80"]
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
Redis backplane şeffaf çalışır. Hub kodunda hiçbir değişiklik yok. Tek instance'dan multi-instance'a geçiş = sadece
AddStackExchangeRedisekle. Client hangi instance'a bağlı olursa olsun mesaj ulaşır.
SignalR yoğun kullanımda Redis Pub/Sub message volume yüksek olabilir. Çok fazla group/user varsa → Redis Streams bazlı custom çözüm düşün.