我阅读了有关映射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; }
}
以下是中间件类的代码:
[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);
}
}
我希望改进这个方法,因为使用这个方法会创建许多不需要的ConnectionIds。此外,使用这个方法将导致Connections表随着时间的推移变得越来越大而没有任何用处。