我理解为什么SignalR不让你访问HttpContext。但是,这对我们来说是相当成问题的。让我解释一下:
我们的应用程序是一个多租户应用程序,用户在登录时选择环境。这基本上是在 HttpSession 中注册 ConnectionStringName。在我们的 SignalR 中心,我们需要访问 Disconnect
上的数据库。但这是不可能的,因为我们目前没有 HttpContext,也无法确定要写入的环境。
任何人都可以向我们提供如何解决此问题的建议吗?我们有点卡在这个问题上。
编辑:如果您的解决方案在负载平衡环境中工作,则为奖励点。
这是一个老问题,但我留下我的答案,以防万一它对那里的任何人都有帮助。
由于集线器扩展Microsoft.AspNet.SignalR.Hub,因此可以访问 HubCallerContext 类型的 Context 属性
此属性公开来自调用方的大量信息:
- 连接标识
- 头
- 查询字符串
- 请求
- 饼干
- 用户
在我的解决方案中,我使用存储在 Context.User.Identity.Name 中的用户名作为键/值存储中的键(在我的例子中是 Redis)来跟踪用户拥有的所有连接。
您可以覆盖 OnConnnect 和 OnDisconnect 以维护与用户关联的连接列表。还可以存储所需的任何其他内容以及连接 ID(在本例中为用户连接字符串)。
如果您使用的是 ASP.NET Core SignalR 3.0(不是 ASP.NET SignalR 2.1),则可以使用Context.GetHttpContext()
获取HttpContext
。
仅供参考,Signalr 3.0 不再具有Context.Request
对象。可以通过访问 IHttpContextFeature in Context.Features[]
来访问请求上下文。我使用了以下内容:
IHttpContextFeature hcf = (IHttpContextFeature)this.Context.Features[typeof(IHttpContextFeature)];
HttpContext hc = hcf.HttpContext;
string myCookieValue = hc.Request.Cookies["Value"];
这可能需要一些空检查,或者可能更干净,但希望这可以节省一些时间。
我遇到了类似的问题,因为我需要识别应用程序的未经身份验证的访问者,以个性化他们对 SignalR 中心的请求。
我已经通过访问"HttpContext.Current.Request.AnonymousId"解决了它。AnonymousId 映射到 SQL 数据库中自实现的会话实体中的临时记录 - 实质上是模拟数据库支持的会话。
这里有一些相关文档,如果您希望自定义 AnonymousId 或初始化数据库条目:http://msdn.microsoft.com/en-us/library/system.web.httprequest.anonymousid.aspx
此外,您应该能够像这样访问 OnDisconnected() 中的 Context:Context.Request.GetHttpContext()。
我希望这有所帮助。
之类的东西来跟踪用户连接时的 ConnectionId。使用SQL Server来存储会话状态也可能有所帮助 http://support.microsoft.com/kb/317604:
SignalR 确实允许您访问 User.Identity.Name 您可以使用这些来跟踪 disoconnect() 何时被触发。
您需要解决方案在负载平衡环境中工作这一事实强制要求您将连接字符串存储在与 Session 不同的环境中。键值存储(如何实现它无关紧要),其中键是 ConnectionId(断开连接时唯一可用的信息),值是连接字符串。如果需要,您可以在任何其他地方继续使用Session,但我认为您应该移动整个应用程序以从那里写入和读取,至少对于该信息而言。