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 roomKey, ChatMessage message, CancellationToken ct = default) { await hubContext.Clients.Group($"chat:room:{roomKey}").ReceiveMessage(message); } public async Task BroadcastSystemMessageAsync(string roomKey, string message, CancellationToken ct = default) { await hubContext.Clients.Group($"chat:room:{roomKey}").ReceiveSystemMessage(message); } public async Task KickUserAsync(int memberID, CancellationToken ct = default) { // 모든 룸 연결에서 해당 memberID 검색 후 강제 종료 // (룸 간 이동 가능하므로 여러 연결이 있을 수 있음) // 현재 설계상 tracker.GetByRoomAsync 는 룸 단위라서 서버 전역 검색은 지원 안 함. // 대신 Kick Pub/Sub 채널을 이용하는 별도 서비스가 처리함 (KickSubscriberService). await Task.CompletedTask; } }