How can I tell if a user has left my website - ruby-on-rails

Is there a way to tell if a user on my website has left (i.e. connection dropped, navigated away etc.) in real time?
I am building a RoR website and want to initiate an event as soon as a user leaves my site for whatever reason (e.g. connection, navigating away from domain etc.)
Thanks in advance for any help.

No, there isn't.
The best you can do is send an AJAX request every X seconds (perhaps only if the user moves the mouse). If the server doesn't receive any requests for 2X seconds, assume that the user left.

Nope.
Http = connectionless

You can do some request in this function:
$(window).bind('beforeunload', function(){
// there
});
Send some Ajax or something to tell the server that this user is leaving the page, but this is not a good idea. In Google analytics and in other statistic services you already can see how long the user stays in your page.

All I can think of is JavaScript onunload event in your body tag... I don't know how viable that is, but in theory you could have that use an AJAX call to send information about an impending disconnect.
Of course, if the browser process is just killed that won't work.
And I'm not sure if Rails has any unique magic that does this same thing (except better).

Related

WaitForInputIdle not waiting for website to fully display

I looked high and low and could not find a satisfactory answer to my problem, which is:
I want to open a website and send it my user id and my password to enter it. I am using a procedure found on StackOverflow that uses CreateProcess and WaitForInputIdle. The problem is that the procedure returns without waiting for the website to fully display, therefore my Id and password end up in the wrong place. Inserting a Sleep(5000) will most of the time work but is not reliable. Can anybody point me in the right direction.
That will never work because WaitForInputIdle returns as soon as the application is waiting for input, but the web browser will not load the web site before that.
You'd have to find another way to do what you want. For example you could create a html form that will post your user id and password to the desired website as soon as it is opened:
How do you force a web browser to use POST when getting a url?
Or host the webbrowser in your application. Then it's in your control and you can send the post by code or be notified when the website has finished loading.

Rails - ensuring only one simultaneous controller hit per user

tl;dr - Is there a way to ensure that a given Rails controller action stops executing when another simultaneous request from the same user comes in?
In my Rails/Angular app, I make requests to the Foursquare API from the client-side. Because they need to be authenticated, and my authentication information should remain secure, I pass these requests through a Rails controller in my own app.
For a more in-depth description of the architecture of this, check out this semi-related question.
My concern, as elaborated there, is that each request to this internal controller takes up server time (and on Heroku, ties up a dyno). I'd tried to make the action as fast as possible, but I'd still like to reduce the amount the server is tied up.
The amount the server is tied up is exacerbated by the real-time nature of the search I'm doing. The request is sent out to my server as a user types, not on enter or anything, because I wanted to allow for auto-suggestion.
I'm debouncing the user input (0.4 seconds), so a the request isn't made til a user briefly stops typing. But if a user pauses a few times while typing, and a request goes out each time, this can quickly cause multiple dynos to get used.
More concretely, assuming a roughly ~1.3s API response time from Foursquare, imagine this scenario: A user types "ameri", then waits 0.4 seconds, then types "can", then waits 0.4 seconds, then types " beauty", completing their query. This would send three separate requests, all of which would need to be handled by different dynos, because none of the requests have a chance to return before the next comes in.
This would either cost me a ton of money (if I have a bunch of users, that means a large number of dynos to protect against concurrency timeouts) or cause really annoying waits on the user front.
So my thought would be that it would be awesome if I could essentially do a retroactive debounce on the server side, by terminating any running requests to Foursquare coming from that user before sending a new request out. That would mean that in the above concrete example, while 3 requests started, only the last request would come back, because the first two would be dropped midstream when a new one came in.
I was thinking of storing some variable in session for each that would be true when a request was executing. Then, the next request wouldn't go out if it was triggered. But that's actually sort of the opposite of what I want, because I want the original request to get canceled when the new one comes in. I just don't know how to access that request from within the latter on.
This feels complicated, so I'm guessing it may be impossible (particularly as each controller action is responded to by a new controller instance), but does anyone know a way to cancel controller actions if the same action is hit by the same user again while the first request is getting resolved?
Thanks!

Tracking time online in MVC4

I have an website build in MVC4 .NET. Now I want to tracking the time user had online in my website. Example: User open browser and then login to my website and active on my website about 30 minutes then close the browser. I want to store 30 minutes to database but I don;t know how to implement it. Please help me because I very need to do it now. Thank you so much
Here is a script that track user login/logout times on a website. It's a simple script that It has used on some of the sites. Also with this script you can see how many users are online at your site.
But the problem is when the user close the browser he do not log out. his session goes to expire
one of the other ways is global action filter that intercepts requests to all actions on all controllers, then you can get the time of each action in the database for the current user and page. To save hitting the database too hard, you could cache these values and invalidate them every few minutes, depending on how much traffic you're dealing with.
UPDATE
about Closing the Browser This is not something that's provided for in the normal web http protocol. There's no real way to know for sure when the browser closes; you can only sort of know. You have to throw together an ugly hack to get any level of certainty and even then it's bound to fail in plenty of edge cases or cause nasty side effects.
The normal work-around is to send ajax requests at intervals from the browser to your server to set up a sort of heartbeat. When the heartbeat stops, the browser closed and so you kill the session. But again: this is a horrible hack. In this case, the main problems are that it's easy to get false positives for a failed heartbeat if the server and client to get out of sync or there's a javascript error, and there's a side effect that your session will never expire on it's own.

Invoke controller action from a web service

I have an ASP.NET MVC application presenting some data and I want it to
open a new tab, or
redirect to a new view
when a web service gives me a signal. This WS is supposed to handle some external data and requests and when some specific action is called, I want it to be able to give my web application some kind of signal.
I was thinking about using Html.Action to an asynch controller but then I don't know how to provide the signal from the WS to the controller (or all instances of them).
Hopefully, it is understandable. Do you have an idea what needs to be done?
Thanks in advance.
So basically your problem comes down to the fact that server state is changed (through WS) and we want to make something happen at the client side where the your web app is being viewed.
Frankly it's not straightforward. Internet works on the Client -> Server architecture. User sends a request to the server, server responds. What you are trying to do is reverse of it. You want to send a request from server to user. HTTP protocol doesn't work like that.
Right now, to do something similar following two strategies are used:
Websockets : try searching them on google. You create a socket between the client and server and once server gets updated by the WS, it sends a request to the client through the socket. You can ask it to navigate to a different view or open a new window. The downside with it is that its not supported by the majority of the browsers. Might take a year or so to be. Not really recommend now.
Polling : You can make Ajax requests from your browser to server in certain intervals (you know like every 5 seconds) and see if the server state has changed or now. If yes, then do your stuff. That's the most common technique. Twitter.com uses it. There is also another version of it called Comet or Long Polling but I won't confuse you with that.
The important thing to note here is that whatever you want to do (open tab, change view etc) you have to do it through Javascript at the client side.
hope that helps

MVC show notification to user when event happens on server

i've got a situtation where we have a web site (mvc project), and a wcf service, when service gets message i need to show a notification to user who's on the web site with this message contents.
would be glad if you can show me the place where to start!
Thank You !
You probably need some javascript on your page that polls the server at a certain interval to check if there is something to show to the user.
Here is a nice article on how to create a WCF service and call it from the browser using JQuery
I think you need to place javascript timer on your page which will do ajax for example: "/Messages/GetLastUnreadMessage".
You'll need to have a bit of javascript that makes an AJAX call back to your site from the client page on a regular basis that checks to see if there are new messages, and displays them if there are.
There's no way for your web server to 'notify' an already rendered client page in the other direction (providing I understand your requirement correctly).

Resources