homepage Welcome to WebmasterWorld Guest from 54.196.201.253
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
Peer Review: polling script that works once even across multiple tabs
A full XHTML file to test, looking for suggestions for improvements.
JAB Creations




msg:4624965
 6:15 am on Nov 21, 2013 (gmt 0)

So I needed to make a quick polling script to check for new emails. The problem is that since I keep multiple tabs open for my site I needed to make sure that the browser would only poll to the server once. I've put together a script that seems to work as desired. When the page is loaded in to two tabs the JavaScript alert() seems to suggest this should work as desired: multiple tabs could be open though only one will actually contact the server. I haven't implemented anything in regards to contacting the server though I put a comment where I would execute the actual polling code.

Save the following as
polling.xhtml and then place it in your root localhost directory as this requires localStorage support. I'm not very concerned about compatibility at this moment in time, this is intended as a proof of concept.

polling.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Polling Example</title>
<script type="application/javascript">
//<![CDATA[
var email_tab = 0;

function mail_notifications_poll()
{
function mail_notifications_poll_settime()
{
email_tab = new Date().getTime();
localStorage.setItem('email_tab',JSON.stringify(new Array(new Date().getTime(),new Date().getTime())));
}

if (localStorage==undefined) {alert('Error: email notifications are not supported in your browser.');}
else if (localStorage.getItem('email_tab'))
{//alert('other tabs are open, email polling may already be occurring.');
//alert(localStorage.getItem('email_tab'));
var a = JSON.parse(localStorage.getItem('email_tab'));

if (email_tab===a[0])
{alert('THIS is the tab polling for new emails! UPDATE a[1] and set it!');
//Poll server here!
mail_notifications_poll_settime();
}
else
{//alert('This is NOT the tab polling for new emails.\n\nWe **ARE** going to see if the tab that should be checking has expired!');
if (a[1]+20000<new Date().getTime())
{alert('old tab not updating, this tab takes over');
mail_notifications_poll_settime();
}
else {alert('The tab polling is still keeping up to date, keep checking any way every 15 seconds.');}
}
}
else
{//alert('no tabs open, set email tab hash!');
mail_notifications_poll_settime();
}

setTimeout(mail_notifications_poll,15000);
}


window.onbeforeunload = function()
{
if (localStorage && localStorage.getItem('email_tab'))
{
var a = JSON.parse(localStorage.getItem('email_tab'));

if (email_tab===a[0]) {delete localStorage['email_tab'];}
}
}


window.onload = function()
{
mail_notifications_poll();
}
//]]>
</script>
</head>

<body>

<h1>Polling Demo</h1>

<p>Open this on a domain such as <a href="http://localhost/polling.xhtml">http://localhost/polling.xhtml</a> in multiple tabs for testing please.</p>

<p>Polling occurs once every fifteen seconds.</p>

</body>
</html>

 

Fotiman




msg:4625131
 4:35 pm on Nov 21, 2013 (gmt 0)

I would make some minor modifications. Below is a refactoring (JavaScript code only):

var tab_id = new Date().getTime();

function mail_notifications_poll() {

var email_tab = localStorage.getItem('email_tab'),
POLL_INTERVAL = 15000;

function mail_notifications_poll_settime() {
localStorage.setItem('email_tab',
JSON.stringify({
id: tab_id,
timestamp: new Date().getTime()
})
);
console.log(localStorage.getItem('email_tab'));
}

function poll_server() {
console.log("Polling server...");
// To be implemented
mail_notifications_poll_settime();
}

if (email_tab) {
email_tab = JSON.parse(email_tab);

if (tab_id === email_tab.id) {
console.log('THIS tab (id: ' + tab_id + ') is the tab polling for new emails.');
poll_server();
}
else {
console.log('This tab (id: ' + tab_id + ') is NOT the tab polling for new emails.');
console.log('Checking if the tab that should be polling has expired...');
if (email_tab.timestamp + POLL_INTERVAL + 5000 < new Date().getTime()) {
console.log('The old tab (id: ' + email_tab.id + ') is not updating, this tab is taking over.');
poll_server();
}
else {
console.log('The old tab (id: ' + email_tab.id + ') is still updating.');
}
}
}
else {
console.log('No tabs are polling yet, so this tab will do it.');
poll_server();
}

setTimeout(mail_notifications_poll, POLL_INTERVAL);
}

window.onbeforeunload = function() {
if (localStorage && localStorage.getItem('email_tab')) {
var email_tab = localStorage.getItem('email_tab');

if (tab_id === email_tab.id) {
delete localStorage['email_tab'];
}
}
}

window.onload = function() {
if (localStorage == undefined) {
alert('Error: email notifications are not supported in your browser.');
// No point going any further
return;
}
mail_notifications_poll();
}


First, I changed "email_tab" to "tab_id" and initialized it to a timestamp immediately. Might also consider validating that no other tab has the same tab_id (chances are unlikely, but if you open multiple tabs at once, the possibility exists).

Next, I renamed your "a" variable to "email_tab", since that's really what represents the tab that's doing the polling. This gets initialized immediately to the value in localStorage (but JSON parsing happens later).

I put all variable declarations at the top of the function, and added POLL_INTERVAL.

Instead of an array containing 2 copies of a timestamp (and rewriting both of those over and over), I used an object that contains an id (the id of the tab that's polling), and a timestamp (the last time it polled). When updating, only the timestamp gets written over.

I moved the check for localStorage == undefined to happen earlier (in the onload function).

The logic in the function then becomes:
1. JSON parse the value in localStorage
2. If this tab's id matches the id in the localStorage, then this is the tab that's polling
3. Else, check the timestamp to make sure the tab that's polling is still active.

I think this is a slightly cleaner implementation, but the basic functionality of what you have seems pretty solid to me. :)

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved