I'm trying to detect if user has my website open in one tab, then opens it in another tab. This should then show a warning to the user on the newly opened tab.
Right now I'm sending a "keep alive" ajax call every second back to the server. This then logs the "last active" time in the database with a unique ID. When a new page is loaded it checks if that user (identified by a userID) was active within the last 2 seconds.
This feels very inefficient. It also doesn't perform well when the user refreshes the page. (which takes less than 2 seconds). I've made the 2 second check longer than the keepalive call to allow for slower connections.
Q) Am I going about this the right way or is there an easier way of doing this? I heard Gmail and Facebook might do something similar but I can't find the site function in which they do it.
Actual code uses lots of in-house functions so here's the general idea:
Pseudo code:
Page load;
[index] PHP: Save tabsessionid, userid, datecreated, lastactive, phpsessionid into database;
[index] JS: Every second, send tabsessionid to keepalive.php
[keepalive] PHP: Check if another session exists in the last 2 seconds
[keepalive] PHP: If exists -> Return "-1"; else -> return "1";
[keepalive] PHP: Update tabsessionid's last active time.
I've tried some of the solutions here but warning the newer tab, not the older one seems to be the tricky part in terms of keeping down latency/time.
I'm trying to detect if user has my website open in one tab, then opens it in another tab. This should then show a warning to the user on the newly opened tab.
Right now I'm sending a "keep alive" ajax call every second back to the server. This then logs the "last active" time in the database with a unique ID. When a new page is loaded it checks if that user (identified by a userID) was active within the last 2 seconds.
This feels very inefficient. It also doesn't perform well when the user refreshes the page. (which takes less than 2 seconds). I've made the 2 second check longer than the keepalive call to allow for slower connections.
Q) Am I going about this the right way or is there an easier way of doing this? I heard Gmail and Facebook might do something similar but I can't find the site function in which they do it.
Actual code uses lots of in-house functions so here's the general idea:
Pseudo code:
Page load;
[index] PHP: Save tabsessionid, userid, datecreated, lastactive, phpsessionid into database;
[index] JS: Every second, send tabsessionid to keepalive.php
[keepalive] PHP: Check if another session exists in the last 2 seconds
[keepalive] PHP: If exists -> Return "-1"; else -> return "1";
[keepalive] PHP: Update tabsessionid's last active time.
I've tried some of the solutions here but warning the newer tab, not the older one seems to be the tricky part in terms of keeping down latency/time.
Share Improve this question edited May 23, 2017 at 12:22 CommunityBot 11 silver badge asked Oct 11, 2013 at 7:52 Jamie TaylorJamie Taylor 4,7656 gold badges46 silver badges67 bronze badges 12-
1
The first thing that crossed my mind: Why not use
sessionStorage
and keep track of tabs there. Listen on theonbeforeunload
event to know when the user has closed a tab. – Johan Commented Oct 11, 2013 at 7:56 -
is
onbeforeunload
reliable enough? I read another solution somewhere saying that you couldn't guarantee it would fire in time. I should also have mentioned this needs to work cross-browser - another plication. Editing that into my post now. – Jamie Taylor Commented Oct 11, 2013 at 7:58 - stackoverflow./questions/3185105/… That should probably be enough as far as the event goes. And sessionStorage is supported everywhere but ie7 if I recall correctly. – Johan Commented Oct 11, 2013 at 8:02
- Sorry, when I said cross browser, I meant if a user opens a tab in Chrome, then a tab in Firefox, it would warn them in Firefox too. Trying to think of better ways to rephrase the question D: – Jamie Taylor Commented Oct 11, 2013 at 8:08
- I think you are going about it the right way. IMO, it's one of those classic problems of trying to maintain state over the stateless nature of HTTP so the solution is always going to feel like hard work. But what you've suggested sounds like a very similar solution I've used for a similar problem I had in the past. – Dave B 84 Commented Oct 11, 2013 at 8:10
4 Answers
Reset to default 3You should keep version of the content, initially at 1, with each submited edit it increases. Submited edits must include version number, which is pared to the current one and the edit is refused if they don't match. It's also possible to make ajax calls to ask for the current version, and warn the user his version is outdated.
The sql update should look like this:
UPDATE table SET .... WHERE id = :id AND version = :version
Then check affected rows, if it's 0, there was a concurent update. This way you won't encounter race condition.
This is just an idea you have to work on:
javascript variables are local to the tab, cookies are mon. You can give each tab an id and pass it around in links and forms*. This id would be stored in a cookie as the active tab id. if a tab finds it does not have and id set, and there's active tab id set, it can use another cookie to ask if there's still such tab with this id, or was closed (and sure, it has to regulary check for this "ask" cookie and answer). Exact implementation depends on what you want to do.
I hope I explained myself clear.
EDIT:
*There's window.name
js property, you can use it as window id, and you don't need to pass it around.
I think u should send data (maybe simple HEAD request) to server from every window with param, contains user uid and window id(random generated once on page load), and check if exists same uid with multiple window id;
Seem this is only way.
Shall I say that it is inappropriate solution to whatever your problem is?
Even if you find a dirty-workaround to prevent people from multi-tabbing on your site, you will not beat the incognito mode. If you do, please do a favour and file the bug report for that browser.