8

I'm working on a PHP/MySQL/Javascript based online chess game. One problem I've encountered is the possibility of a user on one end just closing his browser. Is there any way to reliably detect if someone has been idle/closed the page?

As an added complication, our school server does not support cron jobs -_-

  • 4
    Short Answer : **NO** But still you can ping user at regular intervals to check – Mr. Alien Dec 08 '12 at 08:50
  • 1
    keep in mind that this relies on fact that user **lets** th ping to go on – tereško Dec 08 '12 at 08:52
  • what do you mean by pinging users? – user1880610 Dec 08 '12 at 08:52
  • 1
    you use [xhr](http://en.wikipedia.org/wiki/XMLHttpRequest) to send a request from browser to a server every `X` seconds. – tereško Dec 08 '12 at 08:53
  • But if the person has closed the browser, there will be no request sent. And since I can't run crons, I'm not sure how I would continually check on the server side for no return ping. – user1880610 Dec 08 '12 at 08:55
  • Request will be sent from your side, you wont get the response from client – Mr. Alien Dec 08 '12 at 08:56
  • This is generally achieved with `unbeforeunload` per my answer. – David Titarenco Dec 08 '12 at 08:56
  • Any way I can continually send those requests without cron? – user1880610 Dec 08 '12 at 08:57
  • 1
    @DavidTitarenco , no , it is **NOT** – tereško Dec 08 '12 at 08:57
  • @user1880610 I think you need to explain more about how your game works. Does the game reside on one page and use AJAX to submit moves? Or does it require a form submission that causes the page to reload? How are the separate users communicating their moves? Are you using a database to store things? What do you need to do when the user closes the browser? Is it important to catch when the user closes the browser or when they leave the game's page? I can't see the use of AJAX pinging actually working unless you're doing things a certain way, but you need to explain. – Ian Dec 08 '12 at 09:00
  • We're using a database to store the game board information. I'm using JQuery's .ajax() function to continually receive the board every 2 seconds. Making a move calls another .ajax() function that updates the board stored in the MySQL database. – user1880610 Dec 08 '12 at 09:05
  • The problem I'm trying to solve is when a user just closes the browser, or refreshes, or leaves the page in any way, in my current setup, the server has no way of knowing what has occurred. – user1880610 Dec 08 '12 at 09:06
  • The correct answer to this problem (AJAX polling) was posted several times by several people, and was downvoted to hell. I have no idea why. You folks that like to just come in and downvote stuff without explanation are the worst of the worst on Stack Overflow, and are wasting everyone's time. The person asking the question is without the proper answer, once again. – Brad Dec 08 '12 at 09:27
  • Voting this question for deletion. Someone's most likely trolling here. – David Titarenco Dec 08 '12 at 09:28
  • @DavidTitarenco, Why would you vote this question for deletion? It is a fine question. – Brad Dec 08 '12 at 09:29
  • Because it's a mess. It's been answered several times correctly (by myself included, as you can see) and systematically downvoted. Keeping SO clean is a pretty good general rule of thumb (where you can tell the good answers from the bad) and this question is out of hand imo. – David Titarenco Dec 08 '12 at 09:32
  • Furthermore, it's an exact duplicate of: http://stackoverflow.com/questions/3888902/javascript-detect-browser-close-tab-close-browser – David Titarenco Dec 08 '12 at 09:33
  • @Brad I don't think any answers suggesting AJAX polling were made. There were several that suggested using `onunload` or `onbeforeunload` events. – Ian Dec 08 '12 at 09:35
  • @Ian, I'm not sure at what rep level you can see deleted answers, but I can. It was suggested several times, and all of the answers were downvoted to the point where the posters deleted them. – Brad Dec 08 '12 at 09:36
  • @DavidTitarenco No one answered it correctly (in a reliable fashion), and in no way is it a duplicate. They're not simply asking how to detect if the browser has been closed - they're more asking how to maintain the state of the games via the page being left. You said it yourself, you read more into the explanation than just the title... – Ian Dec 08 '12 at 09:36
  • @ian: there have been two people (prior to my reply) that suggested AJAX polling. I don't think that's the best answer, but again, your rep level (as Brad pointed out) doesn't allow you to see them and this is why you're probably confused as to what I'm talking about. – David Titarenco Dec 08 '12 at 09:41
  • @DavidTitarenco I see. Well, I'm not sure the way the OP is handling a game being played is the best either. I wouldn't say that AJAX should be used for a multiplayer game, especially for one that requires support of something like they're requesting – Ian Dec 08 '12 at 09:44
  • possible duplicate of [Detect window closed](http://stackoverflow.com/questions/9344670/detect-window-closed) – Michael Berkowski Dec 08 '12 at 16:00

3 Answers3

2

The only reliable way to do this is to use a pinging technique to your server, as the other commenters have suggested. This way you control the game, not the browsers. The way you'd have to "track" users is to fire an AJAX call...I think every 5 seconds is often enough...to the server. All this will do is either INSERT something into a "tracking" table or UPDATE a new column you make in your "Games" table to keep track of the last time the user had server activity (ignoring normal moves in the game...you can do this same process for normal moves and reset the interval of pinging as well, to avoid excessive checking). So every time a user makes a move (or something else that requires a server interaction), you would have to make a check for the time of their opponent's last server activity - if the opponent hasn't made a move within 7 seconds of the current time, then the opponent's browser has stopped communicating (for whatever reason). The reason I say 7 seconds is because of extra processing that takes place for server/database communications and any possible network lagging. Since network lagging is probably the bottleneck, you might want to increase this value to something like 10.

Ian
  • 50,146
  • 13
  • 101
  • 111
  • Thank you for a reasonable response! I did not expect so much bickering on SO -_- – user1880610 Dec 08 '12 at 09:59
  • Now, for a separate question: this solution is dependent on one user being active. I have a lobby that displays all available games. Is there any way the server can figure out if both players leave, so that I don't have to display that game in my lobby anymore? The lack of cron becomes a problem here. – user1880610 Dec 08 '12 at 10:01
  • This is where I don't agree with your approach on simply using AJAX for a multiplayer game. This should really all be done with websockets, where you wouldn't need polling and stuff like that. Cronjobs really wouldn't help (unless your lobby page uses polling as well, but then it makes them unnecessary) because the server can't send messages to the client. Like the solution of AJAX polling during the game, you'd have to do something like that in your lobby. The lobby page would have to poll every 5 seconds like before and check to see if both users haven't had activity in the past 7 seconds – Ian Dec 08 '12 at 22:07
1

You can't with exact certainty know whether the client is closed. You can make some qualified guesses, but it will never be reliable.

Maybe you could find a comprise where you are satisfied with knowing if a client session is active or not?

A low-tech solution would be to save the session id (or a selfmade unique identifying string) along with a timestamp. Whenever the client makes a new request (new page load and/or with AJAX), update the timestamp.

Since you don't have access to cronjobs, you need to make another compromise - let the other visitors tell you whether the client still is active. Whenever a visitor loads a page, run through the table which stores the session id's and timestamps and see if any sessions looks older than what you would consider being active.

It's not a sulotion to your exact problem (since it cannot be done) but a low-tech compromise.

Repox
  • 15,015
  • 8
  • 54
  • 79
0

You can simply set a 'RECURSIVE' ajax script on that page and that script silently send updated time to the server after small time period. And on the server you have to write that Request Listener Script to log this details. If you see that a users request is stopped or it is not coming for last some times, then he closed his browser.

Mrinmoy Ghoshal
  • 2,804
  • 1
  • 19
  • 17