在 mvc 身份注销时断开 SignalR 用户

Disconnect SignalR User on mvc Idenity Logout

我正在使用 signalR 跟踪页面上有多少人在线。

当他们用他们的用户登录时更新列表。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using System.Data.Entity;
using System.Threading.Tasks;
using Live_Friend_Message_With_SignalR.Models;

namespace Live_Friend_Message_With_SignalR
{
    public class ChatHub : Hub
    {
        private static List<Tuple<string, ApplicationUser>> _connectedUsers = new List<Tuple<string, ApplicationUser>>();

        public override Task OnConnected()
        {
            if (Context.User.Identity.IsAuthenticated)
            {
                using (ApplicationDbContext db = new ApplicationDbContext())
                {
                    var user = db.Users.FirstOrDefault(i => i.UserName == Context.User.Identity.Name);

                    if (!_connectedUsers.ToList().Exists(i => i.Item1 == Context.ConnectionId && i.Item2 == user))
                    {
                        _connectedUsers.Add(new Tuple<string, ApplicationUser>(Context.ConnectionId, user));
                    }
                }
            }
            else
            {
                if (Context.User.Identity.Name == null)
                {
                    OnDisconnected(true);
                }
            }
            Clients.All.Notification(_connectedUsers.Count);
            return base.OnConnected();
        }

        public override Task OnReconnected()
        {
            return base.OnReconnected();
        }

        public override Task OnDisconnected(bool stopCalled)
        {
            if (_connectedUsers.ToList().Exists(i => i.Item1 == Context.ConnectionId))
            {
                _connectedUsers.Remove(_connectedUsers.FirstOrDefault(i => i.Item1 == Context.ConnectionId));
            }
            Clients.All.Notification(_connectedUsers.Count);
            return base.OnDisconnected(stopCalled);
        }
    }
}

我已经尝试了很多方法来在用户注销时将其从列表中删除,但到目前为止我无法使任何工作正常。

有没有人知道如何做到这一点。

向您的 ChatHub 添加一个方法,以便您可以从用户名查询 ConnectionId。然后做这样的事情;

控制器

public class AccountController : Controller
{
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly IHubContext<ChatHub> _hubContext;

    public AccountController(
        SignInManager<ApplicationUser> signInManager,
        IHubContext<ChatHub> hubContext)
    {
        _signInManager = signInManager;
        _hubContext = hubContext;
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> LogOff()
    {
        var connectionid = ChatHub.GetConnectionIdByName(User.Identity.Name);
        await _signInManager.SignOutAsync();
        await _hubContext.Clients.Client(connectionId).logoff();
        return RedirectToAction(nameof(HomeController.Index), "Home");
    }
}

Javascript

$.connection.chathub.client.logoff = function() {
    $.connection.hub.stop();
}