问题:如何管理匿名用户,以便当 Hub 发出响应时,单个浏览器中的多个选项卡全部更新?
场景如下:
我想将 SignalR 集成到一个项目中,以便匿名用户可以与运算符(operator)实时聊天。显然,已通过 iIdentity 进行身份验证的用户是通过 Client.User(username) 命令映射的。但是目前说一个匿名用户正在浏览 site.com/tools 和 site.com/notTools 我不能只用一个 connectionID 向所有选项卡发送消息。只有一个选项卡收集响应。
我曾尝试使用 IWC 补丁,但该工具无法将聊天信息保存到数据库中,而且我认为通过 ajax 传递变量并不是读取/写入数据库的安全方式。
我还查看了以下内容:Managing SignalR connections for Anonymous user
然而,创建这样的基础并使用 session 似乎不如 Owin 安全。
我想通过在用户每次连接时创建一个虚假帐户并在他们断开连接时删除它来使用 client.user()。但我不想用垃圾帐户填充我的 aspnetusers 数据库上下文,这似乎是不必要的。
是否可以使用 UserHandler.ConnectedIds.Add(Context.ConnectionId);
来映射假用户名?我不知所措。
使用 iUserId 提供程序有意义吗?
public interface IUserIdProvider
{
string GetUserId(IRequest request);
}
然后创建一个数据库来存储 IP 地址到连接 ID 和单个用户名?
数据库:
用户:通过 FK 连接 ID
|userid|username|IP |connectionIDs|
| 1 | user1 |127.0.0.1| 1 |
| 2 | user2 |127.0.0.2| 2 |
connectionIDs:
|connectionID|SignalRID|connectionIDs|
| 1 | xx.x.x.x| 1 |
| 2 | xx.xxx.x| 2 |
| 3 | xx.xxxxx| 2 |
| 4 | xxxxx.xx| 2 |
然后可能围绕连接编写逻辑?
public override Task OnConnected()
{
if(Context.Identity.UserName != null){
//add a connection based on the currently logged in user.
}
else{
///save new user to database?
}
}
但问题仍然存在,当在 websocket 上发送命令时,我将如何处理多个选项卡?
更新 明确地说,我的意图是创建一个实时聊天/支持工具,允许在浏览器中始终进行匿名访问。
客户想要类似 http://www.livechatinc.com 的东西
我已经创建了一个 javascript 插件,无论它在哪个域上,它都可以从集线器发送和接收。 (我的客户有多个站点)拼图中缺少的部分是最简单的,管理匿名用户以允许多选项卡对话。
最佳答案
我不遵循虚假用户帐户的想法(不知道它是否有效),但会开发一个替代方案。
可以通过所有浏览器选项卡共享的 ChatSessionId cookie 并创建以此 ChatSessionId 命名的组来实现该目标。
我从 asp.net/signalr 学习了基本的聊天教程并添加了允许同一用户从多个选项卡聊天的功能。
1) 在“聊天”操作中分配聊天 session ID 以识别用户,因为我们没有用户凭据:
public ActionResult Chat()
{
ChatSessionHelper.SetChatSessionCookie();
return View();
}
2) 进入聊天页面时订阅聊天 session
客户端
$.connection.hub.start()
.then(function(){chat.server.joinChatSession();})
.done(function() {
...
服务器端(集线器)
public Task JoinChatSession()
{
//get user SessionId to allow use multiple tabs
var sessionId = ChatSessionHelper.GetChatSessionId();
if (string.IsNullOrEmpty(sessionId)) throw new InvalidOperationException("No chat session id");
return Groups.Add(Context.ConnectionId, sessionId);
}
3) 向用户的聊天 session 广播消息
public void Send(string message)
{
//get user chat session id
var sessionId = ChatSessionHelper.GetChatSessionId();
if (string.IsNullOrEmpty(sessionId)) throw new InvalidOperationException("No chat session id");
//now message will appear in all tabs
Clients.Group(sessionId).addNewMessageToPage(message);
}
最后,(简单的)ChatSessionHelper 类
public static class ChatSessionHelper
{
public static void SetChatSessionCookie()
{
var context = HttpContext.Current;
HttpCookie cookie = context.Request.Cookies.Get("Session") ?? new HttpCookie("Session", GenerateChatSessionId());
context.Response.Cookies.Add(cookie);
}
public static string GetChatSessionId()
{
return HttpContext.Current.Request.Cookies.Get("Session")?.Value;
}
public static string GenerateChatSessionId()
{
return Guid.NewGuid().ToString();
}
}
关于c# - SignalR C# MVC 将匿名用户映射到客户端 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34913972/