Is it possible to request the time on a client computer with ASP.NET without using javascript?
i don't believe so. javascript executes on the client and therefore has access to the client attributes. asp.net code behind files are procesed on the server and therefore do not have access to client data.
Agree with jmatthews.
What I do is on login to the system, I have javascript to write the client time to a hidden field, then when the page posts I use that to compute an offset vs the server time. Anytime in the application I need the client time I can just apply the offset to the current server time. Saves having to "ask" for it at a random point, if that helps.
The only information about the client that the server can see without JavaScript is what comes over the wire in the HTTP headers. Unfortunately, that doesn't include the current time.
About the closest you can get without script is to measure approximate elapsed time, with coarse granularity. You could do that by setting a cookie with a short expiration time, and then looking to see if the cookie has expired, in which case it will no longer be sent to the server.
Another trick for elapsed time would be to set a short cache expiration time on an object on the page; the object will only be requested again once the cache entry expires.
You can also estimate the current local time at the client by using a GeoIP database to find the country and therefore the time zone.
Related
I have inherited a fix on a classic ASP application where we want to store some user session-specific data to persist across page loads/their session, and need a bit of a refresher.
In the past I have simply used Session variables - ie. Session("SomeVar") = SomeVal.
In IIS on the production box, I noticed that ASP / Session Properties / Enable Session State = false. Setting this to True allowed me to successfully begin using session variables.
I don't want to consume any more resources than necessary on the server. In the past, I believe that I was under the delusional misconception that session variables in classic ASP were stored on the client side. Revisiting this now - the data is retained on the server side.
The string I am saving is a GUID, for roughly 3000 connected clients.
What kind of server impact am I looking at if I implement this, and would using client-side cookies be a better option?
Lets analyse this a bit, a GUID takes about 40 characters as a string hence in Unicode thats 80 bytes, lets call it 100 bytes. 100 * 3000 = 300KB. Can server spare 300K for this? I think the server already in trouble if the answer were no.
However there are other impacts to enable session state. When sessions are enabled ASP adds its own cookie to the client which in size terms is probably equivalent to the one you would need if you were storing your GUID as cookie instead of in the session. Its worth noting that this session ID stored in the cookie uses an algorithm which some say is more predictable (I haven't got any evidence of that myself). Hence if you are using the GUID as some form of authorization then storing the GUID as cookie directly may be better.
There is a further significant change that happens when Session state is enabled. ASP requests from a client must be processed serially, the server will not process multiple requests from the same client in parallel. This is because the Session object is single threaded and since each request from a client needs access to it the requests cannot be processed at the same time.
That last point could have significant impact on the existing behaviour and performance that a client sees especially if AJAX techniques, multiple IFrames or other techniques which result in simultaneous ASP requests being sent to the server are being used.
Hence for the requirement you have my choice would be to store the GUID in a cookie and leave session state turned off.
Multiple servers/server farm? If so you might run into trouble using Session if you load balancer is not set to be "sticky" and send you to the same server each time. Can me a real headache to debug so becareful.
Is there a way to measure this?
Certainly, for get requests, no available headers are being sent consistently from clients.
One idea I got is to get that from query string, but is that possible? Something like (pseudo-code follows)
http://server/default.aspx?t=(new Date().getTime())
Another one that would work is to have users hit a very small page that appends a query string as above, but wanted to avoid a redirection if possible.
(Overall goal is to gather per-request such statistics. The server processing time and server to client are more doable, under some assumptions.)
Thanks in advance.
I've done this through an AJAX request after the initial page load where you have control over the request from the very beginning. Pass the UNIX time in the query string and then when it reaches the server take the difference. I'm not familiar with iis7 so you'd have to make sure that timezone's are accounted for. This number could be very erratic since it's basically just calculating latency and DNS lookups which is different for every client.
Does the request start from an initial page that you have control over it ? in that case you can send the server time with the initial response, and then increment that time second-by-second with a javascript code while the user is on the page. this way you can have a server-synchronized time on the page and when a request goes to be sent from that page you can send that synced time with that request, then all you need is calculate difference on the server.
We have a performance measurement module that relies on HttpModule and HttpHandlers and works like this:
Request comes in to server for a page.
HttpModule_Begin writes start time in the cookie.
HttpModule_End writes end time in the cookie.
On client, when page load is finished, fire off a special request via AJAX
that is handled by HttpHandler_ProcessRequest
In HttpHandler_ProcessRequest subtract DateTime.Now from end time written by the previous HttpModule_End (which is stored in the cookie) and store it in the database.
One thing I forgot to mention: all data is shared via a cookie, so the HttpHandler, just pulls the data from the cookie without any session id's, etc...
All participants are in the same time zone.
This process works fine for most cases, but there are some instances that report network time in excess of an hour!
This indicates a very large passage of time between the the writing of end time and firing off the AJAX request or a large passage of time between firing off AJAX request and the time it gets to the app server.
I am trying to figure what could be causing this issues in the wild. Why does the operation not simply time out?
Extend your troubleshooting: append values to the IIS log (HttpContext.Current.Response.AppendToLog(string)).
The IIS log will show your entries and you can determine when those requests were actually recorded. You can append whatever you want and it shows up in the query field of the log (assuming you're using W3C format.)
If you're experiencing delays in requests, as the evidence suggests, you can verify it.
This will give you the IIS log as a comparative source against the recorded values in cookies.
Are you including some unique id that allows the AJAX request handler to figure out the which end time to use for the calculation? If not, perhaps enough of the page has been rendered on the client that the AJAX request is actually coming before the end time has been written to the database and it is using the wrong end time.
I have an Ajax request to a web service that typically takes 30-60 seconds to complete. In some cases it could take as long as a few minutes. During this time the user can continue working on other tasks, which means they will probably be on a different page when the task finishes.
Is there a way to tell that the original request has been completed? The only thing that comes to mind is to:
wrap the web service with a web service of my own
use my web service to set a flag somewhere
check for that flag in subsequent page requests
Any better ways to do it? I am using jQuery and ASP.Net, if it matters.
You could add another method to your web service that allows you to check the status of a previous request. Then you can use ajax to poll the web service every 30 seconds or so. You can store the request id or whatever in Session so your ajax call knows what request ID to poll no matter what page you're on.
I would say you'd have to poll once in a while to see if request has ended and show some notifications, like this site does with badges for example.
At first make your request return immediately with something like "Started processing...". Then use a different request to poll for the result. It is not good neither for the server nor the client's browser to have long open HTTP sessions. Moreover the user should be informed and educated that he is starting a request that could take some time to complete.
To display the result you could have a"notification area" in all of your web pages. Alternatively you could have a dedicated page for this and instruct the user to navigate there. As others have suggested you could use polling to get the result.
You could use frames on your site, and perform all your long AJAX requests in an invisible frame. Frames add a certain level of pain to development, but might be the answer to your problems.
The only other way I could think of doing it is to actually load the other pages via an AJAX request, such that there are no real page reloads - this would mean that the AJAX requests aren't interrupted, but may cause issues with breaking browser functionality (back/forward, bookmarking, etc).
Since web development is stateless (you can't set a trigger/event on a server to update the client), the viable strategy is to setup up a status function that you can intermittently call using a javascript timer to check whether your code has finished executing. When it finishes, you can update your view.
By default the session expiry seems to be 20 minutes.
Update: I do not want the session to expire until the browser is closed.
Update2: This is my scenario. User logs into site. Plays around the site. Leaves computer to go for a shower (>20 mins ;)). Comes back to computer and should be able to play around. He closes browser, which deletes session cookie. The next time he comes to the site from a new browser instance, he would need to login again.
In PHP I can set session.cookie_lifetime in php.ini to zero to achieve this.
If you want to extend the session beyond 20 minutes, you change the default using the IIS admin or you can set it in the web.config file. For example, to set the timeout to 60 minutes in web.config:
<configuration>
<system.web>
<sessionState timeout="60" />
... other elements omitted ...
</system.web>
... other elements omitted ....
</configuration>
You can do the same for a particular user in code with:
Session.Timeout = 60
Whichever method you choose, you can change the timeout to whatever value you think is reasonable to allow your users to do other things and still maintain their session.
There are downsides of course: for the user, there is the possible security issue of leaving their browser unattended and having it still logged in when someone else starts to use it. For you there is the issue of memory usage on the server - the longer sessions last, the more memory you'll be using at any one time. Whether or not that matters depends on the load on your server.
If you don't want to guesstimate a reasonable extended timeout, you'll need to use one of the other techniques already suggested, requiring some JavaScript running in the browser to ping the server periodically and/or abandon the session when a page is unloaded (provided the user isn't going to another page on your site, of course).
You could set a short session timeout (eg 5 mins) and then get the page to poll the server periodically, either by using Javascript to fire an XmlHttpRequest every 2 minutes, or by having a hidden iframe which points to a page which refreshes itself every 2 minutes.
Once the browser closes, the session would timeout pretty quickly afterwards as there would be nothing to keep it alive.
This is not a new problem, there are several scenarios that must be handled if you want to catch all the ways a session can end, here are general examples of some of them:
The browser instance or tab is closed.
User navigates away from your website using the same browser instance or tab.
The users loses their connection to the internet (this could include power loss to user's computer or any other means).
User walks away from the computer (or in some other way stops interacting with your site).
The server loses power/reboots.
The first two items must be handled by the client sending information to the server, generally you would use javascript to navigate to a logout page that quickly expires the session.
The third and fourth items are normally handled by setting the session state timeout (it can be any amount of time). The amount of time you use is based on finding a value that allows the users to use your site without overwhelming the server. A very rough rule of thumb could be 30 minutes plus or minus 10 minutes. However the appropriate value would probably have to be the subject of another post.
The fifth item is handled based on how you are storing your sessions. Sessions stored in-state will not survive a reboot since they are in the computer's ram. Sessions stored in a db or cookie would survive the reboot. You could handle this as you see fit.
In my limited experience when this issue has come up before, it's been determined that just setting the session timeout to an acceptable value is all that's needed. However it can be done.
This is default. When you have a session, it stores the session in a "Session Cookie", which is automatically deleted when the browser is closed.
If you want to have the session between 2 browser session, you have to set the Cookie.Expired to a date in the feature.
Because the session you talk about is stored by the server, and not the client you can't do what you want.
But consider not using ASP.NET server side session, and instead only rely on cookies.
Unfortunately due to the explicit nature of the web and the fact there is no permanent link between a website server and a users browser it is impossible to tell when a user has closed their browser. There are events and JavaScript which you can implement (e.g. onunload) which you can use to place calls back to the server which in turn could 'kill' a session - Session.Abandon();
You can set the timeout length of a session within the web.config, remember this timeout is based on the time since the last call to the server was placed by the users browser.
Browser timedout did not added.
There's no way to explicitly clear the session if you don't communicate in some way between the client and the server at the point of window closing, so I would expect sending a special URI request to clear the session at the point of receiving a window close message.
My Javascript is not good enough to give you the actual instructions to do that; sorry :(
You cant, as you can't control how the html client response.
Actually why you need to do so? As long as no one can pick up the session to use again, it would expire after that 20 minutes. If resources does matter, set a more aggressive session expiry (most hosting companies did that, which is horribly annoying) or use less objects in session. Try to avoid any kind of object, instead just store the keys for retrieving them, that is a very important design as it helps you to scale your session to a state server when you get big.
Correct me if I am misreading the intent of your question, but the underlying question seems to be less about how to force the session to end when a user closes the browser and more about how to prevent a session from ending until the browser is closed.
I think the real answer to this is to re-evaluate what you are using sessions to do. If you are using them to maintain state, I agree with the other responses that you may be out of luck.
However, a preferred approach is to use a persistent state mechanism with the same scope as the browser session such as a cookie that expires when the browser is closed. That cookie could contain just enough information to re-initiate the session on the server if it has expired since the last request. Combined with a relatively short (5-10 min) session timeout, I think this gives you the best balance between server resource usage and not making the user continually "re-boot" the site.
Oh you have rewritten the question.
That one is absolutely feasible, as long as javascript is alive. Use any timed ajax will do. Check with prototype library http://www.prototypejs.org PeriodicalExecutor or jQuery with the ajax + timer plugin. Setup a dummy page which your executor will call from time to time, so your session is always alive unless if he logouts (kill the ajax timer in the same time) or close browser (which means the executor is killed anyway)