One of the problems I have come across having complex tasks on the browser is with automatic timeouts.
Currently our site has a sliding expiration of 30 minutes. Normally, this isn't a problem because we use asp.net and most of the time the users update one or two fields and then submit the form. This obviously keeps the session active. I have struggled with how to handle this with significantly more complex forms/user interaction where there are few if no round trips to the server.
Now users can view reports, type emails etc. on our site, and I am struggling with how to keep their session active while they're actually using browser but they are not actively posting information back. I would dispense with the sliding expiration, but it's a requirement, so I am stuck with it. Most of our users are outside of the organization, so I can't use any form of SSO.
Does anyone have an elegant solution (I'll even go for an ugly one if it works), or am I out of luck?
Have the browser ping the server via Ajax periodically to keep the session alive. Most sites do something useful in this ping, like save a draft of the user's submission.
We recently went through this in my organization. Although it is not the best solution, and hitting the right session across multiple browser windows is rough, we put a countdown timer on our page, included a button that just went back and hit the server to restart the session, and also provided the user with a JavaScript popup (the user's favorite part of the solution) with a message saying that the session was, say, five minutes from timing out and to hit the "OK" button to restart. Then the button would hit the server to restart the session, restart the timer on the base page, close the popup and the base page didn't need to be refreshed at all.
erickson is on the the right track.
On the areas of the site that are prone to session-timeout due to "complex forms/user interaction where there are few if no round trips to the server", you can place a keepalive control to keep pinging the server, thus keeping the session alive.
Here is a sample control that you can use, or use as a basis for coding your own.
Ah, the age old problem of not wanting to increase the session time because of higher memory usage.
One answer is to also set a cookie that expires after more like a day that will tell the system to still remember the user. That's what eBay does, among others.
Related
I have a Blazor server-side app and after a period of inactivity, the message "Attempting to reconnect to server..." appears.
I need to extend the inactivity period.
My questions:
Is this maybe related to the authentication or application cookie lifetime?
Is it possible to extend the timeout, and if yes, how?
Is it possible to manually disconnect the circuit to test the reconnection code?
That's what I gathered:
the browser tab goes to sleep and Blazor is unable to recover when a user comes back to a page. Switching off power-saving mode of the web browser might help.
the issue of Blazor reconnecting method needs improvement e.g. link link 2. There is a discussion going on GitHub and consensus is that the reconnecting mechanism needs improvement.
Right now we are waiting for a fix, which I saw vaguely scheduled for .NET 8...
The time after the message appears is the timeout for a browser to put tab to sleep. This power saving mode is switched on even on desktops. You can check the setting (and turn it off) in settings of the browser.
As for a command to keep the tab alive, I have not come across such solution. There are a lot of answers online how to reload the page once it goes into sleep, but there are no answers how to prevent it in the first place.
I have even seen a hack involving playing audio to fool heuristics of web browsers which put a Blazor tab to sleep...
My project in MVC is an order carting project.
The carting is done with the following structure.
There is an order object which holds:
cOrder -> List<cOrderItem>
cOrderItem-> List<dressing>, List<topping>, List<specialInst>
I am holding it in Session. Is it the right approach to hold it in Session without losing performance. Or should I follow an alternate approach?
I presume what you mean by "trips to the server" you really mean "trips to the DB" because whenever are dealing with the Session you are at the server anyway.
The Session will do the job, however, there are a couple of caveats that might be a problem
Session is not persistent, it's all stored in memory. This means that there is the potential for you to lose the session at any point e.g. app pool recycle.
Given it's not persistent, this means that a users cart is only maintained within a single session i.e. if the users session expires they will effectively lose their cart.
One approach which I have used in the past is to use a client-side cookie to maintain a basket session, this means
It's persistent storage so it's retained across sessions (not just a single session)
Nothing is stored on the server
It's very quick
There are a couple of small caveats with this approach as well
Browsers need to have cookies enabled
Users can clear their cookies (as such, losing their basket)
However, I've found that these issues are very rarely a problem as most people enable cookies in their browser and most users very rarely clear their cookies (and the chances of them doing it during a session is relatively low).
Yes and no. :)
Placing stuff that needs to survive across requests in the server session is fine for smaller websites, but it does limit scaling; it will be more difficult to distribute the load over multiple server machines, because either the session would need to be replicated to each machine, or all requests from a particular user would need to be routed to the same machine. There are out-of-the-box solutions for this however, it is not that big a deal.
But holding stuff in the session has other downsides. The session timeout for example will kill all the products that were in the cart if the user decides to for for lunch in the middle of his shopping spree.
Ideally, these days, I would be looking at storing the cart locally, in localStorage. Support for this is increasing rapidly. You would have some big advantages over storing it in the session:
Less memory needed on the server(s).
More scalable as there is no server state; each request may be
routed to any server that has capacity at that moment.
No session timeouts killing your shopping cart.
Local code (Javascript) can access the shopping cart without having
to make trips to the server and back.
Option 4 is becoming more important as of late. If you have your data available locally there are many things you can do with it later on that would be more difficult otherwise. Working offline for example could be done that way. You can fill your cart offline and only need to be connected to actually place the order with the webshop.
I am facing an issue in my application that whenever user search for any data and then keep the application idle for like 15-20 mins, and then try to perform any operation on the application, then the application crashes. I am using simple DevEx Grid to show data and ahve details rows and Popup control for that grid.
I think the issue is with the sessions as my application was unable to maintain the session for that duration and due to which application crashes.
Moreover, i have not used any session variables into my application for data.
I cannot find the real cause for this error.
Can somebody help me for the same.
You could write client side javascript to make ajax calls to the server.
This will keep your session alive.
It allows you to have a short timeout at the server, and still a long time out for idle users.
Be sure to have a timeout though, in case your user is away for a hour, the page should log him out.
You can just set the session timeout in IIS to a really high number or minutes (like 1440 for an entire day). This setting is in the "Session State" area.
Another option would be to use Opera as your browser, and load the page once. After that, use Opera's "reload page every..." option to automatically reload the page every minute. This would extend the session forever.
Since you don't store anything useful in session, you should make a way it could reload without crashing. For this you need to anylyse when the crash happens and find a way to prevent the crash. either by initializing with a sane default or catch the exception and start fresh.
Now that the use of one of my asp.net apps has gone up significantly, two odd problems are occurring that are very infrequent, and that I cannot reproduce.
I am at a loss as to how to debug and troubleshoot these problems.
Here are two examples:
One of my aspx pages resets a session state value to 0 on !IsPostBack (is true). However, one of my users at a specific location frequently comes to that page when it is not a postback and the session state value does not get reset on his laptop. (I am basing this statement on how the app subsequently behaves, not on running in debug mode) But the code works and the session state is reset on my laptop when I am sitting next to him running the app on my laptop using the same browser on the same internet connection at the same time. And when this user runs the app on his laptop from home where he has a better internet connection he does not have the problem as frequently.
One of the aspx pages in my app does a server.transfer to itself after running code that saves data to a DB. Almost all the time after the server.transfer the textboxes contain their default value (as they should since !isPostback==True), but about 1% of the time the textboxes contain the previous value. I know that there has been a roundtrip to the server because data has been saved. This problem occurs on the same pcs using the same browsers by the same users doing the same actions. So 99% of the time it works correctly, and 1% of the time they do the exact same thing and it does not work correctly.
How do I even start trying to figure out what is causing these problems if they seem to be occurring randomly?
I suspect that the quality of the internet connection is the issue because it is the one variable that is changing, but how does that info help me?
It's not like I can debug either of these problems by running my app in debug mode.
I am using Asp .Net 3.5, C# 3.5 and the app is run in IE 6-8. (IE 8 in compatibility mode)
I would add logging to code where the problem is occurring. Then inform the users who are having the problem to try and note the time when they run into the issue. Once you have the logs and an approximate time, you can go in and pour over these logs to see if anything points you in the right direction. I would also look at your IIS and Event Logs on the server.
You can install Firefox Throttle plugin to simulate slow connections. Lot's of things can happen in ASP.NET with slow page loads. If the page isn't loaded fully but items are clickable ASP.NET can get really upset with event validation...etc
Also, I encourage you to start logging and tracing the problem areas in your application. You can then correlate that with the IIS request logs and get a fairly accurate picture of whats's happening when.
It seems like you're having problems with Session State. By default, ASP.NET uses InProc session state mode which uses server memory to store values. In many occasions, this can be lost or reset (app pool recycled). Switching to SQLServer Session State might help you solve the issue.
I'm a newbie in ASP and I've encountered worst developer nightmare: I've received fired worker huge ASP.NET project and I must make some changes on it. One of the changes is to prevent opening same site few times on one Active Directory login (different tabs, browsers, etc...)
As I've noticed that app is using session. Any ideas to use session to prevent multiple instances of the same site?
Here is an idea. Use a hidden field with GUID which would be randomly generated by server for each page load. When a request comes to the server it checks if GUID coming is what was generated last time. If it is different or empty (while session is alive) - redirect to some page saying access denied (no new GUID here). If it is correct, serve requested page. Small problem with this would be that if someone closes browser and reopens it he/she would get access denied when trying to use your app again. To minimize that you need to lower session timeout to 1 minute and use AJAX asp:Timer to keep session alive. Remember to exclude keep alive calls (and any other AJAX calls) out of GUID generation/verification pipeline. Of course end of session resets the process. Also it would be good to encourage users to properly log out.
This is relatively simple solution to implement although it is weaker in level of protection than permanent connection. Should be enough for non-technical end users though - depends on your "audience". But even for someone who knows about the mechanism, it would make using two "instances" of application quite difficult.
Do it if you really need to. Generally I agree with Marc that web apps should not be restricted this way. Maybe it is a requirement from someone who can be educated?
You just need to create a persistent connection from each page. If browser navigates from one page to another on a single tab then you'll have a single persistent connection at all times. If you get two parallel persistent connections from same user then the user opened a new tab.
In the master page footer add a script that does an ajax call to the server on a page that doesn't end its response (Like long polling). If another ajax call comes from same user while the last one is connected then this is a second tab.
You might want to checkout SignalR for persistent connection thing. It should be able to switch between web sockets or long polling based on browser capabilities.
You cannot prevent the url from being loaded in multiple browsers or tabs at one time, since this is a client-initiated process.
You could implement a persistent connnection (as suggested by Hasan Khan) to ensure that only one browser window can be active at a time. I would add on to that that when a new window is opened up, you could warn the user that they already have an open connection. If they choose to use the new connection, then you send a message down to the old connection (different browser, tab, etc) that will cause it to clear the browser window for that user.