1

I have a Notification System working with AJAX requests over a file called notification-refresh.php which return a JSON object with new notifications - if it exists. So each user call this file to push notifications to the browser. Everything was fine until each user starts to open a lot of tabs. Each tab request that file in a 3 seconds interval. The number of requests overloaded the server and we've temporarily disabled functionality to save our system.

So, can you guys help me? I don't know if that's possible and I looked for other ways to do notification systems with javascript and PHP only, unsuccessfully.

Is there a way to prevent users from running the same javascript call in multiple tabs? Maybe stop the refresh in hidden tabs...

PS: that's not a server side problem. Even when we disabled the notification function, the number of tiny requests just overloaded.

EDIT: final code

All you guys helped me a lot and I found a fast solution to solve my problem. I'll left the code here as it can help people in the future (or not).

Litle things before start:

  • there's a global variable named canRefresh, responsible to allow or deny access to refresh() function;
  • you don't need to do an extra function as I did because you can get the tab focus state with a single call: document.hasFocus(), but it's recommended if you pretend to use it on distinct parts of your code;
  • I can't show you the entire code, sorry.

    function check() {
    
         if(document.hasFocus() == canRefresh)
    
             return;
    
         canRefresh = !canRefresh;
    
    }
    

It works! Thanks again, guys!

Kaique Garcia
  • 518
  • 3
  • 15

2 Answers2

1

I'd take a look at this post.

  1. When the page loads, create a local storage object, with a timestamp object of when it was put in.
  2. When the page closes remove that local storage object
  3. If the object already exists (If it's older than a certain amount of time), then initiate the refresh sequence, and update the timestamp. This is incase the browser crashes, and doesn't clean up that it's actually refreshed.
  4. If the object doesn't exist, start the refresh process.

You also may want to look into websockets. If a user makes a websocket connection to the server, and one already exists, you should simply disconnect the socket (Or push updates to all sockets, regardless. Should be rather lightweight).

Goodbye StackExchange
  • 21,680
  • 7
  • 47
  • 83
  • hey, thanks for your response. Yeah, local storage would be a nice way to solve this problem but I need to consider old browsers too. I'll take a look about websockets, I didn't think of that. Searching right now. Thanks! – Kaique Garcia Jun 10 '17 at 18:57
  • You may also wish to redesign the back end server `notification-refresh.php`. Cache results for X seconds, so that users don't hit the database multiple times. If multiple pages are open, the database will be queried once, and all future requests (within X seconds) will get a cached version of the page. – Goodbye StackExchange Jun 10 '17 at 19:00
  • That's not possible for now but I'll take your advice. Thanks again! – Kaique Garcia Jun 10 '17 at 19:08
1

Using event onfocus() and onblur() to check if this tab is active or inactive. If it's active (focused), you call the notifications refresher immediately and otherwise, stop calling request to server.

var canCallRequest=true;
function refresh(){
  if(!canCallRequest) return;
  //request here...
};
window.onfocus = function () { 
  canCallRequest= true; 
  refresh();
}; 

window.onblur = function () { 
  canCallRequest = false; 
}; 
Nhon Dinh
  • 211
  • 1
  • 5