无法通过SignalR Hub访问会话信息。 我的设计是错的吗?

我刚刚发现你无法访问SignalR Hub中的当前会话。

简化了我的场景:我试过写聊天。

当前用户的名称保留在会话中。

我已经使用SignalR来更新(一组连接)每个新消息。

现在我看到我无法通过集线器访问当前用户的名称。

我想可能会有一些解决方法,但实现我的设计错了吗?

我不应该为此目的使用SignalR吗? 或者我不应该以这种方式使用Session

您不应该使用Session与SignalR(请参阅SignalR不在服务器上使用Session )。 您可以通过其连接ID识别逻辑连接,您可以将其映射到用户名 。

基本问题是在ASP.NET中序列化对SessionState的访问以确保状态一致性,因此对集线器的每个请求都将阻止其他请求。 在过去,有限的只读访问(我假设(但由于要点已经消失)无法通过将EnableSessionstate设置为只读 ,这可以防止我所描述的锁定问题),但是对此的支持被删除了 。 另请参阅SignalR团队发表类似声明的其他各个地方 。 最后:官方文档中有关于HTTPContext.Current.Session

您可以通过Query String将值从客户端发送到服务器中心。

$.connection.hub.start()方法之前,您可以添加如下内容:

客户端JS代码:

 // Replace "some value" with the session value or anything you want $.connection.hub.qs = { "Name": "some value" }; $.connection.hub.start()...bla bla bla 

在Hub上的服务器端,您可以在任何方法中使用它:

 string ClientValue= Context.QueryString["Name"].ToString(); 

我没有用会话测试,但当然在客户端你可以尽可能地棒。

我处于无法使用用户/身份的情况,因为会话尚未经过身份validation,所以我只使用了实际的会话cookie值。

  [HubName("headerHub")] public class HeaderHub : Hub { static HeaderHub() { EventManager.CartUpdated += Update; EventManager.LoggedOut += Update; EventManager.LoggedIn += Update; } public override Task OnConnected() { var group = Context.Request.Cookies["ASP.NET_SessionId"].Value; Groups.Add(Context.ConnectionId, group); return base.OnConnected(); } private static void Update(object sender, SessionEventArgs e) { var hubContext = GlobalHost.ConnectionManager.GetHubContext(); hubContext.Clients.Group(e.SessionId).onUpdateHeader(); } } 

我相信有人会发现这个解决方案有问题,如果有的话可以自由发表评论,因为我想要一个更好的方法来完成将会话绑定到一组客户端来通知。

最好的方法之一是使用Cookie而不是会话。 因为如上所述,你不能使用session。 所以当用户登录到您的系统时,将其唯一标识符(例如用户名)放在cookie中。 然后使用cookie,你想要访问会话。 如下……

  public class CustomUserIdProvider : IUserIdProvider { public string GetUserId(IRequest request) { return request.Cookies["ODPUserID"].Value; } }