I would like to flush a user's session with my website as soon as they close their web browser. How do I go about implementing that?
This is not easy as http is stateless. So you don't have an open connection which is closed when the browser closes. No way is guaranteed to work. A connection could be dropped, or power go down which would make any 'onClose' event unreliable.
You can time out sessions after a certain amount of inactivity. However there is no guarantee that a user hasn't just gone to lunch and wants an open session when they return.
If you are worried about indicating people as offline you could do some polling in ajax to keep sessions alive and destroy sessions that have not been used in longer than the poll interval. But if you are just worried about resources I would guess that this will do more harm than good.
Make an ajax call at onbeforeunload() event and call :
Session.Abandon();
You have no event on server-side triggered when user closes window or leaves the page, you can use the timeout of sessions the check it, and then, ensure the session does't dies on an idle user, that could be at the bathroom, or making coffe, validating it with AJAX or so.
MakeDummyRequest(); // with a simple http request, you can keep your session alive.
As other indicated your best bet is probally to make an Ajax call which will keep the session alive. This call can occur at fast interval if you keep it lean. Then you can use some sort of session timeout algorithim.
With that said there a couple of things to note. You will probally want to build a way in the protocol to force a user to logout of the application. Imagine that a user is logged in to your application and he goes home for the weekend without shutting down his computer.
Over the weekend you do a deploy which will invalidate all the ajax communication becuase you modified the protocol or something. Unless you force him out he will continue to be logged in and could be getting errors when he comes in Monday morning.
Related
I'm building a chat app.But on logout button I can change bit value in database from 1 if user login to 0. But if user close the app or exit the browser without hitting logout, how can I change the bit value to 0?
Need answer programmatically.
When you close your browser, your webserver won't receive any feedback. Most browsers also do not allow you to implement javascript that does this. The only way to track this is by using something that polls your server periodically. (As #scgough put in the comments, SignalR is one of these technologies that you can use to do this.)
The downside of these techniques is that web browsers will generate web traffic to your webserver periodically to send 'heartbeat' signals, which in turn keeps the session alive for as long as the browser is open. This means this will consume a bit more web traffic and server resources.
I want to have single user login in my web site, i.e a user can't logi n with one userid and password from different places at same time.
It can be done simply by maintaining a flag in database and altering it on user logout and login, but what about if the user doesn't press logout button and:
closes the browser(here I can alter database flag through window.unload event)
network crash (real problem is here).
Can anyone suggest how to deal with system/network related problems? I don't want to use session.end() because sometimes it fires after a default timeout (~20 min).
Can I use signalR to create a server timer to monitor if user is alive or not?
SignalR will suffer from server crashes. SignalR does its best to ensure that events are triggered prior to shut down but there are cases when a server dies that will result in you having invalid entries in your db.
An approach that is used by https://jabbr.net/ is it logs every user off on server start. Therefore whenever your SignalR server starts: run cleanup on your database. In all other situations you can rely on SignalR to track your users appropriately.
To address your #1: SignalR will actually send an abort command to the server on unload, however if that command doesn't get sent for whatever reason the server will still timeout the connection and will eventually trigger OnDisconnected on the hub.
What I am trying to do with SignalR:
1- Setting the hidden field from a session UserID on page load and send this ID back to server's SignalR Hub to start the polling thread for given user.
2- Terminate the thread when user leaves the site.
Right now I am doing AJAX requests to server every 30 secs per user to check for new user messages.I Just want to replace it with SignalR. I am able to create the user level thread in a HUB when the users session is created by setting the hidden field on page load and then setting the session variable via ajax request so the new thread is not created for the same user again and again e.g page refresh. The thread is periodically checks after (15 sec) for newly arrived messages. The main issue is how do I terminate the thread created for a specific user when its session ends. Is this the right way to use SignalR ?
This doesn't sound like good design - polling is never good, not for this kind of problems anyway. It would be better if you could deliver the message instantly. Are you using multiple webservers? If not, then deliver the messages locally inside the application. If you are using multiple webservers, consider using something like RabbitMQ, Redis or similar to send messages between the servers.
I have a relatively simple problem, which I cannot tackle without a lot of ugly workarounds. Basically, I am developing a payment gateway client, whereby the process is that the website informs the payment server of the payment to be done, client is transferred to payment server, and once payment is done, payment server informs the website on a seperate thread that the payment was done, and redirects the client. Now, the client can be 'received' on the website before the notification of the payment was received. Thus, I need to program the system to wait until the notification is received or 30 seconds at most.
Once the notification is received, an Order entity is marked as 'Paid'. The problem is this:
Client is redirected to website before, Order.Paid is still false
After 1 - 5 seconds, notification is received and Order is marked as true
Due to Nhibernate session management, Client still sees the Order.Paid as false on the other thread.
To make matters worse, sometimes the client's Order is then flushed on End_Request, and the Order.Paid is again reset to false.
The only way I tried that seems to work is that I dispose of the Nhibernate session explicitly before waiting, and then constantly create a new session until it is found as paid. However the problem is since the original session was removed, lazy loading for any entities already loaded before hand will stop working and generate errors.
It looks simple in my mind but yet seems to be quite complicated due to session management, any ideas how to go about it?
Thanks!
From the time I posted the question, I've managed to find a solution to this.
Basically, how NHibernate works - If any exception occurs on a session, the session must be disposed. This also applies to StaleObjectException, when using optimistic concurrency. The reason the client was still seeing is as 'not paid' was because the session was not being disposed.
A book snippet on Google Books explains this in a bit more detail:
http://books.google.com.mt/books?id=eMOYUycDaoUC&pg=PT213&lpg=PT213&dq=nhibernate+staleobjectexception+dispose&source=bl&ots=rg9YHt58gc&sig=W9FoTm8_4DT3PvMKGLrddG3lSxs&hl=en&sa=X&ei=FGp-UNr4FI7Vsga2nIDwBw&ved=0CGAQ6AEwCA
In an asp.net web form, I keep getting a connection reset error message. The page is doing a some long running processing (about 2-5 minutes).
I have no problem when the web request comes from the same machine as the web server. But when the request originates across the network, I get a connection reset error about 1:30 or 2 minutes into waiting for a response.
I have set the in web.config for this application and put the application it's own application pool.
What else can I try?
Edit
The purpose of this page is to accept input from the user, calculate something, and send the result back to them. The long running calculation isn't something I can offload until a later time.
A common way to handle this is to kick of a background thread to process your data, but immediately return an identifier to the browser, normally as a link. When the link is clicked, the server checks to see if processing is complete - if it is, show the results, if not, display a "please wait" message and the link again, or auto-refresh the page...
Do not make the browser wait for this long. Make the request asynchronous, make it return right away. If you need to make user wait - do it using Javascript