Limiting number of users accessing asp.net website - asp.net

What is the best way to limit the number of (concurrent) users accessing a web application that any one can introduce for selling website/application to client and how to increase the number of users accessing it remotely?

If you use the in-process session state management, you can use the HttpApplicationState class, by introducing the Global.asax file and putting something like this in the code behind:
void Application_Start(object sender, EventArgs e)
{
Application["ActiveSessions"] = 0;
}
void Session_Start(object sender, EventArgs e)
{
try
{
Application.Lock();
int activeSessions = (int) Application["ActiveSessions"] + 1;
int allowedSessions = 10; // retrieve the threshold here instead
Application["ActiveSessions"] = activeSessions;
if (activeSessions > allowedSessions)
System.Web.HttpContext.Current.Response.Redirect("~/UserLimitReached.aspx", false);
}
finally
{
Application.UnLock();
}
}
void Session_End(object sender, EventArgs e)
{
Application.Lock();
Application["ActiveSessions"] = (int)Application["ActiveSessions"] - 1;
Application.UnLock();
}
Then, in the UserLimitReached.aspx you would call HttpSession.Abandon() to effectively terminate the current session so it does not count towards the limit. You'll have to figure out the rest yourself. :)

One way would be to track active sessions in a database, and each time a user logs in, check the number of active sessions. If it is below a threshold, let them in, if not, bounce them.
To administer this number remotely, a simple admin form that lets you update the threshold in the database is simple enough.

In addition to the previous answers, I think you will need to introduce your own timeout so that sessions aren't left lingering and locked. Rather than use sessions, if you have a login, you can monitor it based on logins and keep them active by recording the most recent activity per user in a dictionary/array. That should make it easy to see which users are using the site, and which are the n most recently active users. If you tie that with the sessions, you could expire sessions used by the least recently active user. The effect of this is that if more than the specified number of users try use the website, some (the least active) will continually need to login. Given the disconnected nature of web apps, I think you may have to allow a certain % of grace so that when limited to 20 users, you actually allow maybe 22 to be concurrently active.

Related

Why does my ASP.NET keep-alive logic not work?

In order to ensure that my session always stays on, I created a simple stayalive.aspx page. The header of the page contains metadata to refresh the page every 5 minutes.
In my page-load logic, I simply set a value into session.
protected void Page_Load(object sender, EventArgs e) {
System.Web.HttpContext.Current.Session["Alive"] = 1;
}
My understanding is that as long as you keep putting a value in the session, the session will continue to stay alive. However, this does not seem to be working. I still get a session timeout in about 30 minutes.
I am wondering if anyone has any insight on why is not working.
Note that the sessionstate as well as forms authentication timeout values in web.config are set to 300 (5 hours).
One thought I had was, instead of setting the same value on the session, I set a different value each time:
System.Web.HttpContext.Current.Session["Alive"] = DateTime.Now;
Do you think this would help?
Adding a value in to the session is not required to session alive. If you keep on refreshing the aspx page, session should automatically extend.

ASP.net: How to list a WebApplication All users Session

I want to know my website memory usageļ¼Œfirst i want to know Session detail of all users,this will help me decide whether to change sessionState Mode to "SqlServer" or "StateServer".
How can i do?
Thanks
For website memory usage, I would look at perfmon. If I really wanted to count how much memory I was using in each user session, I would do that count when adding not when abandoning the session. This could be tricky if you've got Session["foo"]=bar all over the place, it needs to be wrapped up somehow.
If you do change to out of process session state, you will need to test everything that touches the session. Your session variables are crossing process boundaries, they need to be serializable and there are definitely some things that don't work.
I am not sure if this will help you solve the problem but you can try this piece of code in Session_End event... Assuming that this event is fired from your logout process..
This is the last of the events where Session Variable is available.
protected void Session_End(object sender, EventArgs e)
{
string strMessage = string.Empty;
for (int i = 0; i < this.Session.Count; i++)
{
strMessage += string.Format("Session of {0} Value is {1}", i.ToString(), this.Session[i].ToString());
strMessage += "/n";
}
}
this.Session.Count should give you the number of sessions in the server for the application. This solution may hold good only if your application is hosted in single web server and not on a web server farm. I am ignorant of how sessions are handled in a web server farm.

Is setting the value of Server.ScriptTimeout enough to prevent page timeouts?

On an administrative page with a long running process we're setting the following:
protected void Page_Load(object sender, EventArgs e)
{
this.Server.ScriptTimeout = 300;
//other code
}
Is this enough that should prevent that page from timing out as it does what it needs to? I have no control over the process and how long it runs but we've found that 5 minutes is more than enough time, yet we're still getting intermittent errors of:
System.Web.HttpException: Request timed out.
We've tried upping the value to 600 with really no difference and in any testing we've done we can never get the actual process to run for that long. Is there elsewhere that we need to be setting timeout values that won't affect the entire application and only the specific page we need the longer timeout value on?
I think you should never have a "script" that can take up to 5 min to run in Web App ,expecially into the page load! Why don't you create a web service or somethig that wrap this process? then you can use any Async pattern to invoke it avoiding to make the page stack on one the same call
anyway have a look at the link below for more detail about the Default server time out
http://msdn.microsoft.com/en-us/library/ms524831(VS.90).aspx

Timer Class in ASP.NET

I have this code in the asp.net application start evert, and I'm not really familar with the Timer class but what I want to do is have one Trigger that goes off every night at 11 pm, one that goes off at 5:30 in the morning and then every hour after that.
private System.Threading.Timer timer;
protected void Application_Start(object sender, EventArgs e)
{
int intervalMilliseconds = 60 * 1000;
timer = new System.Threading.Timer(new System.Threading.TimerCallback(TimedEvent), null, intervalMilliseconds, intervalMilliseconds);
}
protected void Application_End(object sender, EventArgs e)
{
if (timer != null) timer.Dispose();
}
private void TimedEvent(object stateInfo)
{
MyClass.ExecuteCode();
}
*Please no answers in the way of "don't use asp.net to do triggers because of the lifecycle".
*Again - please no posts on what not to use. I've received two post both telling me what not to use and both not related to my question which is about the Timer class and how to use it.
From your question i'm assuming you don't have full control over your hosting environment, so will try to avoid the schedule it... etc answers.
Having said that, you still need to be aware of the asp.net lifecycle, and your trigger approach is fraught with dangers.
Do you get enough traffic that the application won't end unexpectedly? Do you know the configuration of IIS, so recycling is not a worry?
I can see three approaches:
I would recommend having a page, which uses some sort of key, which is only known
by the caller. Have this page triggered by a watchmouse (See: http://www.watchmouse.com/en/), or scheduled crawler on a pc/server which will always be on, at the times you need it to be triggered.
An alternative would be to trigger a database process, which runs when needed to.
Depending on your environment, this can be scheduled too.
Another would be to check a log file, on users accessing the page, and if it is the first access within the hour, trigger your process. (Do this for whatever period you need.)
However this depends entirely on how heavily your site is accessed, and may not work reliably.
When you create your timer and hook up its tick/elapsed event, set the interval to be every 5 minutes or so.
Then in the tick/elapsed event handler, check the current time and perform an action where necessary. Obviously you will also need to record when an actino has been performed so you don't perform it at 10:58 and 11:03 pm.
Have a look at Quartz.NET, which will allow you to set up cron-like triggers.
Maybe a different way of doing what you want: Instead of relying on ASP to be active, perhaps you can just use the windows scheduler to schedule your event. It has more of the scheduling features you want and will be likely be more reliable as well as already debugged. Your timed event can be as simple as accessing http://localhost/YourApp/.aspx. You'll get the same effect with the added benefit that if your app happens to have recycled, your event will still execute as the 1st request.
You can do the kind of thing you're describing by using the inbuilt ASP.NET Cache.Add CacheItemRemovedCallback delegate. It's a bit of a roundabout way of using it, but you can do effective scheduling this way.
There's an article here showing how to do it.
More information on the CacheItemRemovedCallback here.
Edit: I know you said no services, but if you check the server and find you can use Scheduled Tasks, you can use that to run a console app on a specific schedule like some other other answers mention.

How does one discard a session variable while closing Web Page?

We are following a procedure in our work while developing a web page, is to bind page to one or more session variables, these session variables are used only for that page, to hold current processing objects, so while closing page no need for them.
How could I discard these session variables while closing page?
Any suggestions regarding that technique or how to solve that problem?
There is no server-side event that is raised when a page is left/closed. Also the Session_End event (mentioned in other answers) is not called when a page is left, since the user might navigate to other pages of the same web application (and therefore the session will continue to exist).
I can think of 3 possible ways to solve (or work around) this issue:
1 - use ViewState to store data with page-scope. This is what ViewState is made for, and unless you have a lot of data, it should not be a problem. If you have a lot of data, remember, that it will be serialized/deserialized and sent to the client/back to the server for every request (which may result in large requests and therefore bad performance).
2 - instead of putting the data into the session, put it into the Cache (with a low sliding expiration timeout). On your page, you can access your data in the same way as from the session, i.e. data = Cache["data"], but you have to be prepared that the data was removed from the Cache (you have to re-load it again from DB for example), if the time between two requests was bigger than the expiration time.
3 - use the client-side (javascript) onUnload event, and trigger some action (e.g. a ajax callback) to remove the data from the session. But I think the onUnload event is not reliable (it will not be fired in any case, e.g. when the browser is terminated by a crash or with the task manager, or if javascript is disabled).
If you use variables for only that page, store them in viewstate. ViewState is suitable for page scoped variables.
If you are using ASP.NET sessions (which you probably are), you can add a global.asax file to your soluting. In there this event-delegate is to be found (if not, create it):
protected void Session_End(object sender, EventArgs e)
{
}
.. In here you can clear your session collection.
protected void Session_End(object sender, EventArgs e)
{
Session.Clear();
}
This will be fired when the session expires or when a user clicks logout :)

Resources