在 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();
}
我正在使用 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();
}