control user's online status in asp.net - asp.net

I my application I do not want the same user name login at the same time,so I have and idea but I am not sure if it is correct.
1) When a user login,update the status(the "isOnLine" column in the user table in db) and save its login time in the session ,something like:
Inside the login method:
DateTime ltime=Datetime.now();
Dbservice.executeSql(update User set(isOnLine,lastLoginTime) value("1",ltime));
Session["logintime"]=ltime;
When another user try to login,check the table to see if the status of this user is logined or not.if yes,set the "isOnline" to "0",then he can login now.
2)In each protected page's Page_Onload() method,check if the login time in the session is equal to the time in db:
string logtime=Dbservice.executeSelect("select lastLoginTime from user where xxxxx").Rows[0]["lastLoginTime"];
if(!Session["logintime"]==logtime){
//this user should offline now,redirect it to the login page
}
I wonder if my way is right or not?
Also,I have to write the check logic in each protected page's Page_onLoad method,so there are so many repeat codes,any ideas to avoid this?
Since all the page in our site is protected!.
Thanks.
UPDATE:
It is not allowed two user online at the same time,but it is allowed the later user with the correct pasword can force the former user offline. For example:
user1 login with "username=bill" and
"password=000",then he is online now.
then user2 try to login with
"username=bill" and
"password=123",since his password is
not valid,so his request is denied.
user3 try to login with
"username=bill" and
"password=000",since his password is
valid,so he have the choice to make
the user1 offline.
In this case,when the later user login sucessfully,but the session of the former user is also exist,so I have to check if it is online or not according the "logintime" in the session.

If you are not going to use web farm (or web garden) scenarios then you may use in memory structure to keep track of logged in users. For example, a static global variable of dictionary type (accessed in thread-safe way).
For general purpose robust solution, you need to keep this information in database (as illustrated by you). I haven't understood the purpose of checking against logged in time against session. For correct solution,
You need a database table that will track user's session. Important field will be last accessed time and active/inactive state.
At the time of login, if active session for same user exists in db then user cannot be logged in
A job to mark session inactive after specific time-out. This time-out has to be slightly larger (say x minutes) than web server session time-out.
Periodic refresh from application code to reset the last accessed value in db so that job will not mark session inactive.
Because db time-out = web server time-out + x, you can club the refreshes for x minutes, reducing your database trips. For example, say x = 3 minutes then all requests within 3 minutes will not modify last accessed time in database (there by reducing database trips). You can track last database update time in session state and in each request check against this value to see of database needs to be updated or not (i.e. current time > last database update + x then update last accessed value in database).
Third step (job) is optional because you may modify your check in #2 to see if login attempt is after n minutes (where n > session timeout) of last accessed time.

For the logic to check if user is already online, I may want to put it in the Global.asax Application_AcquireRequestState event since all pages is protected.

Related

Firebase inactive user removal from database list

This is my Firebase database structure:
// Registered users
users{
9BKlHH11NvU1kQdpwSaFshNJn8C2{
foo: foo
bar: bar
B5Lq9RquOvcK7CLhh1Mdq0qWCqO2{
foo: foo
bar: bar
// Connected users inside the lobby
Lobby{
9BKlHH11NvU1kQdpwSaFshNJn8C2,
B5Lq9RquOvcK7CLhh1Mdq0qWCqO2
So everytime a registered user logs in and enters the lobby, his uid is added to the lobby list so everybody sees him. If he logs out there's a process to remove him from the lobby list.
Now the problem is; what would be the best approach to remove a user that has closed the browser/app without leaving the lobby so the rest of the users don't see someone that is not actually connected in that list? Is there a timeout function maybe?
There is no timeout function.
Though on the application end, you can add and check the entry in Lobby, and send the beacon request in every 10 or 30 sec or more to make the entry in lobby valid.
And in the UI, while listing Users in the Lobby, if Lobby entry is older than the beacon time, you can either not list them or send a request to remove them.
It will be better to just skip the addition of that User in the UI, let the old entries be there. Sending the removal request will be contradicting, and will arise conflicts if more front ends are sending request to remove same User from Lobby. But, its all up to your app structure and Use Case.

How to send only one email when error occurs in aspx.net

So I have an aspx application that generates an error when the database goes down. I would like the application to send one and only one error when this occurs. Otherwise if multiple users hit the application I could get tons of emails, especially because the page refreshes.
I don’t want to use a database because that may be the reason for the error. I tried using a session variable, but it didn’t work. Any ideas?
My session variable code:
'We only want to send out this email if we it has not yet been sent this session
If Session("AlreadySentStaleDBemail") Is Nothing Then
SendEmailToTeam("The Results Database has not inserted any entries in over 60 minutes.")
Session("AlreadySentStaleDBemail") = "email sent already"
End If
Try using an application variable:
Application("AlreadySentStaleDBemail")

Symfony, Swift Mailer, CRON JOBS, & Shared Hosting Server

Before I tackle this solution, I wanted to run it by the community to get feedback.
Questions:
Is my approach feasible? i.e. can it even be done this way?
Is it the right/most efficient solution?
If it isn’t the right solution, what would be a better approach?
Problems:
Need to send mass emails through the application.
The shared hosted server only permits a maximum of 500 emails to be sent per hour before getting labeled a spammer
Server timeout while sending batch emails
Proposed Solution:
Upon task submittal (i.e. the user provides all necessary email information using a form and frontend template, selects the target audience, etc..), the action will then:
Determines how many records (from a stored db of contacts) the email will be sent to
If the number of records in #1 above is more than 400:
Assign a batch number to all these records in the DB.
Run a CRON job that:
Every hour, selects 400 records in batch “X” and sends the saved email template until there are no more records with batch “X”. Each time a batch of 400 is sent, it’s batch number is erased (so it won’t be selected again the following hour).
If there is an unfinished CRON JOB scheduled ahead of it (i.e. currently running), it will be placed in a queue.
Other clarification:
To send these emails I simply iterate over the SWIFT mailer using the following code:
foreach($list as $record)
{
mailers::sendMemberSpam($record, $emailParamsArray);
// where the above simply contains: sfContext::getInstance()->getMailer()->send($message);
}
*where $list is the list of records with a batch_number of “X”.
I’m not sure this is the most efficient of solutions, because it seems to be bogging down the server, and will eventually time out if the list or email is long.
So, I’m just looking for opinions at this point... thanks in advance.

Is it possible to persist WebTestContext across ASP.NET load test session?

I want to load test an enterprise Web application (which I did not build), using a Visual Studio 2010 Ultimate Load Test. I want each virtual user to log in at the beginning, and log out at the end of their run of random tests. I can properly configured the load test to do so. However, there is a complication. The session key is injected into the URL, like this:
http://ProductName/(S(ilv3lp2yhbqdyr2tbcj5mout))/System/Container.aspx
I converted the Visual Studio WebTests to coded tests, and then retrofit them with code that uses the session-specific URL. This works fine. What I need to do is persist this session encoded URL across the various tests that specific virtual user runs, starting with the login WebTest class, to the logout WebTest class.
The individual WebTest classes are capable of logging in and out at the beginning and end of each test. However, this is not an accurate representation of normal use. This application emulates a mainframe terminal, and never cuts the connection or session between Web browser requests. Each session is one long, interactive HTTP request, just like a mainframe terminal interacts with, for example, an IBM AS400. Usert typically log in to the mainframe at the beginning of day, and (should) log out at the end of day. Likewise, this Web application maintains the HTTP request until the user logs out, or the IIS session timeout occurs. Therefore, it is important I keep the same session in the URL, between all tests, to ensure memory leaks and other nasty bugs don't accumulating.
Please share your thoughts!
Problem 1: persist the session id across test iterations
You can store data in the 'user context' which is persistent across test iterations. It is found in the WebTestContext having the name '$LoadTestUserContext'. (But note that this context parameter only appears in load test runs, not in standalone web test runs)
// within WebTestPlugin.PreRequest() or MyExtractionRule.Extract()
// e is the corresponding eventargs object...
LoadTestUserContext userContext = (LoadTestUserContext)e.WebTest.Context["$LoadTestUserContext"];
...
// setting the value in the user context (i.e. in the extraction rule)
userContext["sessionId"] = "(extracted session id)";
...
// getting the value from the user context (i.e. in WebTestPlugin PreWebTest event)
e.WebTest.Context["sessionId"] = userContext["sessionId"];
You'll have to add a WebTestPlugin (that fetches the value from the user context into the web test context) to all of your web tests to make the value available across all tests.
Problem 2: Login/Logout only at start and end of load test
extract the login and logout functionality into their own separate tests (remember that the logout test also needs the WebTestPlugin that fetches the stored sessionId)
in the Load Test, the Edit Test Mix dialog lets you specify an Initialize and Terminate test: set these to the Login and Logout tests you just created
in the Load Test Scenario, set "Percentage of New Users" to 0.
Some additional explanation of the "Percentage of New Users" setting
The "Percentage of New Users" setting is poorly named and does not indicate its full behaviour.
When a "New User" starts a test iteration, it takes a new $WebTestUserId (and gets a new fresh user context, which you don't want)
When a non-"New User" starts a test iteration, it keeps the same old $WebTestUserId (and the old user context, which you do want)
So far so good. But the unexpected part is this:
Each "New User" executes the following during a load test:
Initialize > web test iteration > Terminate
A non-"New User" executes the following for the entire duration of the load test:
Initialize > iteration1 > iteration2 > ... > iterationN > Terminate
In other words, "New Users" are constantly logging in and out (which you don't want). Non-"New Users" only login and logout once in the entire load test, and continually run test iterations for the duration (which you do want).

Sending alert to pages in asp.net

I am working on web application , in my project there is some type of testing and task assignment to employees.
Now when an employee complete a task and assigned to a user the user automatically get the message on his page ( there is 3 user accessing application , one is admin , second is tester and third is verifier ...both of them works on different pages , now when admin assign a task the tester automatically get a notification " new message " ( for this i am using master page)..on whatever page the tester is on working... now if the tester is completes it 's task and assign to verifier , verifier must get notification "new message" ... and so on..)
for this a have put a button on master page ..and also i have make a windows service that runs on every minute , now my problem is how i sent the message from windows service to my master page button ( that i change text of button).
Is this idea working ?
Why do you need to window service to run in background? Is there any specific reason to have the windows service for these requirements?
As per your detailed description what I understood is that when the employee completes a task and assigned to a user the user automatically get the message on his page. So when the employee is working and completed means they will click on some button that their work is completed. Then while clicking on the button, you just write the code for sending the mail to the tester. like the same way, when the tester is completed their work and click on the testing completes, send a mail to the reviewer and so on..Then where is the need to have a window service for this to send the mails?
All the requirements can be achieved through the simple send mail code.
Let us know if you need any more help or if you don't understand the exact scenario or if anything is missing in the requirements.
Hope it will be helpful to you.
I don't think it is possible to send from a windows service informations to asp.page. You can create a button that can query a webservice about new tasks (but you are counting on the user to press it).
Another more "friendly" way is to have a timer in javascript that uses ajax requests to get new tasks.

Resources