【问题标题】:How to use SignalR to re-direct after Session timeout?会话超时后如何使用 SignalR 重定向?
【发布时间】:2020-09-19 11:01:14
【问题描述】:

我正在使用 SignalR 在会话超时后重定向我的应用程序:

void Session_End(object sender, EventArgs e)
    {
        var HubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
        HubContext.Clients.All.clientListener(false);}

还有我的 Hub 类:

public class MyHub : Hub
{
    public void ServerListener(bool result)
    {
        Clients.Caller.ClientListener(result);
    }
}

JavaScript:

(function () {
var myHub = $.connection.myHub;
$.connection.hub.start()
     .done(function () {
         console.log("Connected");
})
.fail(function () {
    alert("Failed!");
})

myHub.client.clientListener = function (data) {
    if (data == false)
        window.location.href = "/Home/Index";//@Url.Action("Index","Home");
}
})();

我面临的问题是:

  1. 当连接多个用户时,所有用户都会同时注销,即使他们在不同时间登录也是如此。
  2. 即使发出常规请求,也会发生注销重定向。

如果有人能告诉我如何在不调用 Session_End() 的情况下进行“服务器推送”,那真的会对我有所帮助,因为我想使用“In Proc”以外的其他会话状态。

【问题讨论】:

    标签: signalr session-state session-timeout


    【解决方案1】:

    关于问题 #1:

    由于您使用的是HubContext.Clients.All.clientListener,所有连接到 SignalR 的用户确实都会收到来自服务器的消息 - 他们何时登录到您的应用并不重要。

    您应该使用本指南从服务器向特定用户发送消息:https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections。 我个人喜欢单用户组的想法https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections#single-user-groups

    至于附加的问题,只要您可以通过GlobalHost.ConnectionManager.GetHubContext&lt;MyHub&gt;() 获得集线器引用,您所要做的就是调用已注册的客户端方法来执行服务器推送(例如Clients.Group(userid).clientListener(false))。这不是必须专门在 Session_End() 上完成的事情。

    【讨论】:

    • 客户端如何知道会话已超时以调用服务器函数? @mauriciorcruz
    • @InnocentCriminal 我以为您想在会话超时之前从服务器调用客户端方法。澄清一下 - 您是否尝试专门使用 SignalR 让客户端了解会话状态?
    • 不,我也在使用 signalR 进行实时聊天。谢谢@mauriciorcruz
    【解决方案2】:

    我所做的是:

    1. 在 Page_Load 上,我使用 Session.SessionId 更新隐藏标签
    2. 在客户端启动集线器之前通过查询字符串传递它:
        $.connection.hub.qs = { "sessionId": $("#lblSessionId").text() };
    
    1. 在集线器 OnConnected/OnReconnected 的服务器端,我调用此方法将 sessionId->connectionId 的相关性存储在字典中:
    private void AddConnectedClient()
    {
        // read the [ASP.Net] sessionId we send from client in queryString
        string sessionId = Context.Request.QueryString["sessionId"];
        if (!string.IsNullOrEmpty(sessionId))
            sessionIdToConnectionId.AddOrUpdate(sessionId, Context.ConnectionId, (k, v) => Context.ConnectionId);
    }
    
    1. 现在在 Session_End 我有这段代码(GetConnectionIdFromSessionId 是我在集线器中添加的静态方法,用于从 #3 中显示的 sessionIdToConnectionId 字典中读取):
    protected void Session_End(object sender, EventArgs e)
    {
        // look for signalR connecitonId
        string connectionID = YourHub.GetConnectionIdFromSessionId(Session.SessionID);
        if (connectionID != null)
            GlobalHost.ConnectionManager.GetHubContext<YourHub>().Clients.Client(connectionID).onSessionExpired();
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 2013-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多