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);
}
}