ASP.net Core - обработка клиентской информации на стороне сервера после отключения Signalr - PullRequest
0 голосов
/ 29 сентября 2019

Я в основном пытаюсь выполнить какую-то работу с базой данных, если пользователь был отключен от signalR более чем на 10 минут. Я поместил таймер в OnDisconnectedAsync Хаба (). Проблема, с которой я сталкиваюсь - это ObjectDisposedException для вещей, которые мне нужны для доступа к базе данных. У меня возникают те же проблемы, когда я обхожу таймер и пытаюсь сделать вызовы непосредственно в OnDisconnectedAsync (). Я предполагаю, что все было разрушено к тому времени, когда я делаю это в OnDisconnectedAsync ().

Я пробовал все, что я могу найти в течение нескольких дней, но, похоже, ничего не работает. Как правильно решить эту проблему?

public class RangeHub : Hub
{
    private readonly IHubContext<RangeHub> _hubContext;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IDashboardService _service;
    private readonly ApplicationDbContext _context;
    private readonly ISubscriptionService _subscription;
    private readonly HOptions _hOptions;
    //private Timer disconnectTimer = new Timer();
    private CustomTimer disconnectTimer;

    private string UserId
    {
        get
        {
            //return User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier).Value;
            return Context.UserIdentifier;
        }
    }

    public RangeHub(IHubContext<RangeHub> hubContext, UserManager<ApplicationUser> userManager, IDashboardService service, ApplicationDbContext context,
                               ISubscriptionService subscription, IOptionsMonitor<HOptions> hOptions)

    {
        _hubContext = hubContext;
        _context = context;
        _userManager = userManager;
        _service = service;
        _subscription = subscription;
        _hOptions = hOptions.CurrentValue;

        disconnectTimer = new CustomTimer
        {
            Interval = 30000,
            AutoReset = false
        };
        disconnectTimer.Elapsed += DisconnectTimedEvent;
        //disconnectTimer.Elapsed += (sender, e) => DisconnectTimedEvent(sender, e, UserId);
        //disconnectTimer.Interval = 30000;//120000;
        //disconnectTimer.AutoReset = false;
    }

    public override Task OnConnectedAsync()
    {
        Log.Information("OnConnectedAsync: CONNECT TO CLIENT");
        System.Diagnostics.Debug.WriteLine("OnConnectedAsync: CONNECT TO CLIENT");

        //If timer was running, stop timer/reset
        if(disconnectTimer.Enabled)
        {
            //reset timer
            disconnectTimer.Stop();
        }

        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        //TODO: This is firing off when the dashboard is left, need to fix
        Log.Information("OnDisconnectedAsync: DISCONNECTED FROM CLIENT");
        System.Diagnostics.Debug.WriteLine("OnDisconnectedAsync: DISCONNECTED FROM CLIENT");
        _service.StopActiveEnvironment(UserId);
        //_hubContext.Clients.
        //TODO: place logic here to stop environment and stop user's time
        disconnectTimer.userId = UserId;
        disconnectTimer.dashService = _service;
        disconnectTimer.dBContext = _context;
        //disconnectTimer.Start();
        //*is this for a single user? will this effect all users at once?

        return base.OnDisconnectedAsync(exception);
    }

    public void DisconnectTimedEvent(object sender, ElapsedEventArgs e)//, IDashboardService dashService)
    {
        //Shut down the range
        Log.Information("DEBUG Timer");
        Log.Information("UserId: " + ((CustomTimer)sender).userId);
        Log.Information("Shutting down environment due to signalR disconnection timer.");

        //Van - 9-28-2019: Not using await here. This should be the last thing done before the instance of this class is destroyed.
        //  Using await takes too long and the Hub object is already destroyed before its finished.
        //_service.StopActiveEnvironment(((CustomTimer)sender).userId);
        //Task.Run(async () => await _service.StopActiveEnvironment("051735c4-fa6d-4d90-9f76-b540aaa110bc"));
        //Task.Run(async () => await _service.StopActiveEnvironment("051735c4-fa6d-4d90-9f76-b540aaa110bc")).WaitAndUnwrapException();
        try
        {
            var func = ((CustomTimer)sender).dashService.StopActiveEnvironment(((CustomTimer)sender).userId);
            func.WaitAndUnwrapException();
        }
        catch (Exception ex)
        {
            Log.Error(ex.ToString());
        }
    }
}

class CustomTimer : Timer
{
    public string userId;
    public IDashboardService dashService;
    public ApplicationDbContext dBContext;
}
...