using Application.Abstractions.Crypto; using Microsoft.AspNetCore.SignalR; namespace Web.Api.Hubs; public sealed class CryptoHub : Hub { // ─── Market-specific subscriptions ──────────────────────── public async Task SubscribeMarket(string market) { if (string.IsNullOrWhiteSpace(market)) { return; } var lower = market.ToLower().Trim(); await Groups.AddToGroupAsync(Context.ConnectionId, $"ticker:{lower}"); await Groups.AddToGroupAsync(Context.ConnectionId, $"trade:{lower}"); await Groups.AddToGroupAsync(Context.ConnectionId, $"orderbook:{lower}"); await Groups.AddToGroupAsync(Context.ConnectionId, $"candle:{lower}"); } public async Task UnsubscribeMarket(string market) { if (string.IsNullOrWhiteSpace(market)) { return; } var lower = market.ToLower().Trim(); await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"ticker:{lower}"); await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"trade:{lower}"); await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"orderbook:{lower}"); await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"candle:{lower}"); } // ─── Global tickers subscription ────────────────────────── public async Task SubscribeTickers(string? quote = null) { var group = string.IsNullOrWhiteSpace(quote) ? "tickers" : $"tickers:{quote.ToLower().Trim()}"; await Groups.AddToGroupAsync(Context.ConnectionId, group); } public async Task UnsubscribeTickers(string? quote = null) { var group = string.IsNullOrWhiteSpace(quote) ? "tickers" : $"tickers:{quote.ToLower().Trim()}"; await Groups.RemoveFromGroupAsync(Context.ConnectionId, group); } }