using CallCenter.Caches; using CallCenter.Realtimes; using CallCenter.Users; using Microsoft.AspNetCore.SignalR; using XF.Domain.Dependency; using XF.Domain.Exceptions; using XF.Domain.Https; namespace CallCenter.Api.Realtimes; public class CallCenterHub : Hub { private readonly ISessionContext _sessionContext; private readonly IWorkRepository _workRepository; public CallCenterHub(ISessionContext sessionContext, IWorkRepository workRepository) { _sessionContext = sessionContext; _workRepository = workRepository; } /// /// Called when a new connection is established with the hub. /// /// A that represents the asynchronous connect. public override async Task OnConnectedAsync() { var userId = _sessionContext.RequiredUserId; var work = await _workRepository.GetCurrentWorkByUserAsync(userId, Context.ConnectionAborted); if (work == null) throw new UserFriendlyException($"未查询到上班记录, userId: {userId}"); work.SignalRId = Context.ConnectionId; await _workRepository.UpdateAsync(work, Context.ConnectionAborted); //todo 清理对应work cache await base.OnConnectedAsync(); } /// Called when a connection with the hub is terminated. /// A that represents the asynchronous disconnect. public override Task OnDisconnectedAsync(Exception? exception) { //todo 1.清理user与connectionId关联关系记录 return base.OnDisconnectedAsync(exception); } } public class RealtimeService : IRealtimeService, IScopeDependency { private readonly IHubContext _hubContext; private readonly IUserCacheManager _userCacheManager; public RealtimeService(IHubContext hubContext, IUserCacheManager userCacheManager) { _hubContext = hubContext; _userCacheManager = userCacheManager; } public async Task RingAsync(string userId, RingDto dto, CancellationToken cancellationToken) { var work = _userCacheManager.GetWorkByUser(userId); if (string.IsNullOrEmpty(work.SignalRId)) throw new UserFriendlyException("无效signalr.connectionId"); await _hubContext.Clients.Client(work.SignalRId).SendAsync("Ring", dto, cancellationToken); } }