using Application.Abstractions.Chat; using Microsoft.AspNetCore.SignalR; namespace Web.Api.Hubs; public sealed class ChatHubService( IHubContext hubContext, IChatConnectionTracker tracker ) : IChatHubService { public async Task BroadcastMessageAsync(string channelSID, ChatMessage message, CancellationToken ct = default) { await hubContext.Clients.Group($"chat:channel:{channelSID}").ReceiveMessage(message); } public async Task BroadcastSystemMessageAsync(string channelSID, string message, CancellationToken ct = default) { await hubContext.Clients.Group($"chat:channel:{channelSID}").ReceiveSystemMessage(message); } public async Task KickUserAsync(int memberID, CancellationToken ct = default) { // 모든 채널 연결에서 해당 memberID 검색 후 강제 종료 // (채널 간 이동 가능하므로 여러 연결이 있을 수 있음) // 현재 설계상 tracker.GetByChannelAsync 는 채널 단위라서 서버 전역 검색은 지원 안 함. // 대신 Kick Pub/Sub 채널을 이용하는 별도 서비스가 처리함 (KickSubscriberService). await Task.CompletedTask; } }