Conoscere il numero preciso di utenti connessi in un’applicazione ASP.NET non è possibile, sfruttando ad esempio le Membership API è possibile ottenere il numero di utenti connessi usando come criterio discriminante il timeout della Session (Membership.GetNumberOfUsersOnline()). In questo modo però è possibile monitorare solamente gli utenti loggati e comunque il numero rimane piuttosto approssimato.
Personalmente non ho mai avuto la necessità di tenere una traccia più accurata a scopo statistico, ma vediamo comunque come risolvere il problema :-).
Ah, il famigerato evento
Session.End *non* è deterministico, quindi non lo si può sfruttare per questo obiettivo.
La soluzione è piuttosto semplice:
- un WebService che i client chiamano ciclicamente
- un timer Javascript che richiama il WebService
1) L’attributo ScriptService permette di chiamare il web service tramite AJAX.
[WebService(Namespace = "http://eyeopen.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class AliveService : WebService
{
[WebMethod]
public void SendAlive()
{
////string sessionId = HttpContext.Current.Request.Params["ASP.NET_SessionId"];
string sessionId = HttpContext.Current.Request.UserHostAddress;
UsersManager.RegisterUser(sessionId);
}
}
2) Il file Javascript necessario a chiamare il web service:
function SendAlive() {
EyeOpen.UsersMonitor.Web.AliveService.SendAlive();
}
function AliveTimerTick() {
SendAlive();
setTimeout(AliveTimerTick, 1000);
}
if (typeof (Sys) !== "undefined") {
Sys.Application.notifyScriptLoaded();
}
setTimeout(AliveTimerTick, 1000);
3) Infine la reference al file Javascript tramite lo ScriptManager
e la reference al web service:
<asp:ScriptManager ID="scriptManager" runat="server">
<Scripts>
<asp:ScriptReference Path="~/Js/Alive.js" />
</Scripts>
<Services>
<asp:ServiceReference Path="~/Core/AliveService.asmx" />
</Services>
</asp:ScriptManager
La rappresentazione della classe di supporto al web service:
In sostanza il web service lato server viene chiamato da un timer javascript ogni secondo, con un basso carico di rete e sul server, segnalando la presenza dell’utente, nel momento in cui vengono chiuse tutte le pagine che richiamano il servizio entro 10 secondi (il tempo di timeout si gestisce tramite web.config) l’utente viene cancellato dalla lista degli utenti connessi.
E’ sufficiente inserire lo ScriptManager in tutte le pagine (ad esempio tramite MasterPage o da codice) e il sistema viene esteso a tutta l’applicazione web.
Qui si trova il progetto di esempio:
EyeOpen.UsersMonitor.Web.
Matteo Migliore.