ChannelStatusBroadcaster.cs 1.3 KB

123456789101112131415161718192021222324252627282930313233
  1. using Application.Abstractions.Hub;
  2. using Microsoft.AspNetCore.SignalR;
  3. using Microsoft.Extensions.Logging;
  4. namespace Infrastructure.Hubs;
  5. internal sealed class ChannelStatusBroadcaster(
  6. ILogger<ChannelStatusBroadcaster> logger,
  7. IHubContext<AppHub, IAppHubClient>? hub = null
  8. ) : IChannelStatusBroadcaster
  9. {
  10. public async Task BroadcastAsync(string channelSID, bool isLive, int viewerCount, string? videoId, CancellationToken ct = default)
  11. {
  12. if (hub is null)
  13. {
  14. logger.LogWarning("[ChannelStatus] hub is null — broadcast skipped: SID={SID}, isLive={IsLive}", channelSID, isLive);
  15. return;
  16. }
  17. logger.LogInformation("[ChannelStatus] Broadcast → SID={SID}, isLive={IsLive}, viewers={Viewers}, videoId={VideoId}",
  18. channelSID, isLive, viewerCount, videoId);
  19. // 그룹 기반 fan-out — 사이드바/WatchView 가 AppHub.JoinChannel(channelSID) 로 가입한 클라이언트만 수신
  20. // 이전 Clients.All 은 30초 주기에서 모든 접속자에게 N(채널)×M(사용자) fan-out 발생
  21. await hub.Clients.Group($"channel:{channelSID}").ReceiveChannelStatus(new
  22. {
  23. channelSID,
  24. isLive,
  25. viewerCount,
  26. videoId
  27. });
  28. }
  29. }