I read this topic which is about enhancing the method for tracking online users using database. In short, the method use the following database :
public class ConnectedClient
{
public long ID { get; set; }
[StringLength(100)]
public string ConnectionId { get; set; }
public ConnectionStatus Status { get; set; }
public string ApplicationUserID { get; set; }
public string UserAgent { get; set; }
public DateTimeOffset LastActivity { get; set; }
//Relationship
public ApplicationUser ApplicationUser { get; set; }
}
And for tracking online users :
public class PresenceManager
{
private const int zombiePeriodThreshold = 2;
private readonly ITransportHeartbeat _heartbeat;
private readonly TimeSpan _checkInterval = TimeSpan.FromSeconds(60);
private readonly int _zombieThreshold;
private Timer timer;
public PresenceManager(ITransportHeartbeat heartbeat)
{
_heartbeat = heartbeat;
_zombieThreshold = (int)_checkInterval.TotalSeconds * zombiePeriodThreshold;
}
public void StartMonitoring()
{
if (timer == null)
{
timer = new Timer(t =>
{
try
{
Check();
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
}
}, null, TimeSpan.Zero, _checkInterval);
}
}
//EF6 adds much better support for contains in queries http://bit.ly/1wmQ2VQ
private void Check()
{
using (var db = new ApplicationContext())
{
//Update active connections
var activeConnections = _heartbeat.GetConnections().Where(b => b.IsAlive).Select(b => b.ConnectionId);
db.ConnectedClients
.Where(c => activeConnections.Contains(c.ConnectionId))
.ToList()
.ForEach(c => c.LastActivity = DateTimeOffset.UtcNow);
//Remove zombie connections
var zombies = db.ConnectedClients.Where(c => SqlFunctions.DateDiff("ss", c.LastActivity, DateTimeOffset.UtcNow) >= _zombieThreshold).ToList();
var zombieUserIDs = zombies.Select(b => b.ApplicationUserID);
db.Users
.Where(c => zombieUserIDs.Contains(c.Id))
.Where(c => c.ConnectedClients.Count <= 1)
.ToList()
.ForEach(u => u.Status = UserStatus.Offline);
db.ConnectedClients.RemoveRange(zombies);
db.SaveChanges();
}
}
}
I understand all the code above, the only thing that I don’t know is where I should create instance of PresenceManager
and how to pass the parameter heartbeat
to it.
Take a look at the answer provided here.
ASP.NET MVC OWIN and SignalR - two Startup.cs files
While the question is not directly related to yours they inadvertently asnwered where to create instance of PresenceManager
and how to pass the parameter heartbeat
to it:
public void ConfigureSignalR(IAppBuilder app) {
var heartBeat = GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>();
var monitor = new PresenceMonitor(heartBeat);
monitor.StartMonitoring();
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
And then call it from the main Start up like so
public void Configuration(IAppBuilder app) {
ConfigureAuth(app);
ConfigureSignalR(app);
}