【发布时间】:2015-09-28 15:53:17
【问题描述】:
我读到了这个topic,关于将 SignalR 用户映射到连接。简而言之,该主题解释了四种映射方法,我想使用第四种方法(永久,外部存储)。该方法使用 SQL Server 数据库存储ConnectionId,当客户端连接时(当OnConnected 方法被触发时)和当客户端关闭浏览器时(当OnDisconnected 方法被触发时)它只是使ConnectionId无效。
这是数据库的代码:
public class UserContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Connection> Connections { get; set; }
}
public class User
{
[Key]
public string UserName { get; set; }
public ICollection<Connection> Connections { get; set; }
}
public class Connection
{
public string ConnectionID { get; set; }
public string UserAgent { get; set; }
public bool Connected { get; set; }
}
这里是 hub 类中的代码:
[Authorize]
public class ChatHub : Hub
{
public void SendChatMessage(string who, string message)
{
var name = Context.User.Identity.Name;
using (var db = new UserContext())
{
var user = db.Users.Find(who);
if (user == null)
{
Clients.Caller.showErrorMessage("Could not find that user.");
}
else
{
db.Entry(user)
.Collection(u => u.Connections)
.Query()
.Where(c => c.Connected == true)
.Load();
if (user.Connections == null)
{
Clients.Caller.showErrorMessage("The user is no longer connected.");
}
else
{
foreach (var connection in user.Connections)
{
Clients.Client(connection.ConnectionID)
.addChatMessage(name + ": " + message);
}
}
}
}
}
public override Task OnConnected()
{
var name = Context.User.Identity.Name;
using (var db = new UserContext())
{
var user = db.Users
.Include(u => u.Connections)
.SingleOrDefault(u => u.UserName == name);
if (user == null)
{
user = new User
{
UserName = name,
Connections = new List<Connection>()
};
db.Users.Add(user);
}
user.Connections.Add(new Connection
{
ConnectionID = Context.ConnectionId,
UserAgent = Context.Request.Headers["User-Agent"],
Connected = true
});
db.SaveChanges();
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
using (var db = new UserContext())
{
var connection = db.Connections.Find(Context.ConnectionId);
connection.Connected = false;
db.SaveChanges();
}
return base.OnDisconnected(stopCalled);
}
}
我想增强这种方法,因为使用这种方法会创建许多根本不需要的 ConnectionId。此外,使用这种方法,连接表将随着时间的推移而扩大,而没有任何用处。
【问题讨论】:
-
是否需要维护多个连接ID?您是否需要支持
a single user connected on two or more machines simoulathenously? -
在我的应用程序中,用户可能使用多个浏览器或多个设备,所以我有一个要求,同时支持两台或多台机器。
标签: asp.net sql-server asp.net-mvc signalr signalr-hub