KickSubscriberService.cs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. using Application.Abstractions.Cache;
  2. using Application.Abstractions.Chat;
  3. using Application.Abstractions.Hub;
  4. using Infrastructure.Hubs;
  5. using Microsoft.AspNetCore.SignalR;
  6. using StackExchange.Redis;
  7. using Web.Api.Hubs;
  8. namespace Web.Api.Services;
  9. public sealed class KickSubscriberService(
  10. IConnectionMultiplexer redis,
  11. IHubContext<ChatHub, IChatHubClient> hubContext,
  12. IHubContext<AppHub, IAppHubClient> appHubContext
  13. ) : IHostedService
  14. {
  15. public async Task StartAsync(CancellationToken cancellationToken)
  16. {
  17. await redis.GetSubscriber().SubscribeAsync(
  18. RedisChannel.Literal(CacheKeys.ChatKickChannel),
  19. async (_, connectionId) =>
  20. {
  21. if (!connectionId.IsNullOrEmpty)
  22. await hubContext.Clients.Client(connectionId!).Kick();
  23. });
  24. // AppHub 전역 접속자 강제 종료 (Admin 현재 접속자 페이지)
  25. await redis.GetSubscriber().SubscribeAsync(
  26. RedisChannel.Literal(CacheKeys.AppKickChannel),
  27. async (_, connectionId) =>
  28. {
  29. if (!connectionId.IsNullOrEmpty)
  30. await appHubContext.Clients.Client(connectionId!).Kick();
  31. });
  32. }
  33. public async Task StopAsync(CancellationToken cancellationToken)
  34. {
  35. await redis.GetSubscriber().UnsubscribeAsync(
  36. RedisChannel.Literal(CacheKeys.ChatKickChannel));
  37. await redis.GetSubscriber().UnsubscribeAsync(
  38. RedisChannel.Literal(CacheKeys.AppKickChannel));
  39. }
  40. }