witryna ASP.NET ograniczenie liczby zalogowanych użytkowników na stronie

0

Witam, to jet mój pierwszy post na tym forum, tak więc witam wszystkich serdecznie. Mam problem z tworzoną przeze mnie witryną ASP.NET. Chodzi o maksymalną liczbę aktualnie zalogowanych użytkowników na stronie. Chcę liczbę tę ograniczyć do jednego użytkownika zalogowanego w danym czasie. Próbowałem to zrealizować w poprzez modyfikację kodu w pliku Global.asax. Poniżej kod:


<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e) 
    {
        Application["OnlineUsers"] = 0;
    }
    
    void Application_End(object sender, EventArgs e) 
    {
    
    }
        
    void Application_Error(object sender, EventArgs e) 
    { 
      
    }

    void Session_Start(object sender, EventArgs e) 
    {
        Application.Lock();
        Application["OnlineUsers"] = (int)Application["OnlineUsers"] + 1;
        Application.UnLock();
    }

    void Session_End(object sender, EventArgs e) 
    {
        Application.Lock();
        Application["OnlineUsers"] = (int)Application["OnlineUsers"] - 1;
        Application.UnLock();
    }
           
</script>  
 

Następnie w pliku *.aspx głównej strony mojej witryny stworzyłem etykietę wyświetlającą liczbę aktywnych użytkowników na stronie:

 
Liczba użytkowników przeglądających witrynę: <%= Application["OnlineUsers"] %>

Odpowiednio zmodyfikowałem plik web.config:

<system.web>
<sessionState mode='InProc' cookieless='false' timeout='5'></sessionState>
		<compilation debug="true" targetFramework="4.0"/>
<authentication mode="Forms">
   <forms loginUrl="~/Logowanie.aspx" timeout="4" slidingExpiration="true"/>
</authentication>
</system.web>
 

Plik ukrytego kodu strony "Logowanie.aspx" wygląda następująco:

 protected void Page_Load(object sender, EventArgs e)
    {
        if (User.IsInRole("Administratorzy") || User.IsInRole("Sekretarze") || User.IsInRole("Inni"))
        {
            Response.Redirect("~/AlreadyLogged.aspx");
        }
        else
        {
            int ActiveUsers = (int) Application["OnlineUsers"];
           
            if(ActiveUsers > 1)
            {
                Response.Redirect("~/LimitUzytkownikowPrzekroczony.aspx");
            }
        }
    }

Niestety powyżej przedstawione moje rozwiązanie nie do końca działa to prawidłowo. Problem polega na tym, że przy wejściu na stronę (po opublikowaniu jej na IIS7) liczba użytkowników odwiedzających stronę wynosi 1, co znaczy, że również są brani pod uwagę anonimowi użytkownicy bądź też użytkownicy nieprzydzieleni do żadnej z trzech ról. Skutkuje to tym, że w momencie, kiedy obydwaj anonimowi użytkownicy wejdą na stronę, to nie ma możliwości zalogowania się. I tu pierwsze moje pytanie, czy istnieje możliwość, aby wyświetlać tylko i wyłącznie liczbę tylko ZALOGOWANYCH użytkowników? (dane użytkowników są przechowywane w tabeli Aspnet_Users w mojej bazie)

Druga sprawa - chodzi o timeout sesji w pliku web.config. Problem polega na tym, że gdy już jestem zalogowany jako użytkownik np. przynależący do roli "administratorzy" to po wylogowaniu się, do końca timeoutu sesji cały czas ten użytkownik będzie widniał jako aktywny na stronie (czyli jeszcze przez 5 minut - w tym czasie nikt inny nie może się zalogować na stronie). Czy jest taka możliwość, aby w momencie wylogowania się użytkownika od razu wygasła jego sesja?.

Trzecim problemem (będącym w zasadzie skutkiem dwóch poprzednich problemów) jest to, że dopóki nie minie te 5 minut, po których wygaśnie sesja, to przy każdorazowym uruchomieniu witryny z serwera IIS zwiększa się liczba użytkowników odwiedzających stronę - każde uruchomienie to nowa sesja anonimowego użytkownika. Po pięciu takich uruchomieniach jest już 5 użytkowników odwiedzających stronę - każdorazowo tworzy się nowa sesja. Niemożliwe jest wówczas zalogowanie się na stronę.

Czy można w pliku global.asax w jakiś sposób określić, aby sesja była tworzona tylko dla zalogowanych użytkowników, bądź też po prostu w taki sposób wyświetlać liczbę użytkowników na stronie, aby liczba ta informowała tylko o zalogowanych użytkownikach?

Niestety Membership.GetNumberOfUsersOnline() nie zdaje egzaminu, userIsOnlineTimeWindow="60" - na podstawie którego pobierane są dane o zalogowanych użytkownikach powodowałoby zmianę liczby zalogowanych użytkowników na stronie dopiero po godzinie.

Jako że nie jestem zaawansowanym programistą (właściwie dopiero rozpoczynam swoją przygodę z C# - do czego zmusiła mnie praca magisterska:)), powyższe kody mogą wydać się śmieszne dla bardziej zaawansowanych programistów, proszę to uwzględnić przy analizowaniu moich powyższych wypocin.

0

znaczy, że również są brani pod uwagę anonimowi użytkownicy
Ale sam to tak oprogramowałeś, więc o co chodzi?
Jeśli user się loguje to dodawaj go do liczby userów. Jak się wylogowywuje lub kończy się jego sesja dekrementuj licznik.

chodzi o timeout sesji
Oprogramuj że na wylogowanie dekrementujesz licznik. Lub na wylogowanie wywołaj na obiekcie sesji metodę Abandon.
http://msdn.microsoft.com/en-us/library/ms178581.aspx
http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.abandon.aspx

1 użytkowników online, w tym zalogowanych: 0, gości: 1