0

I having a real time feature in my website that open new window on socket.io event fired from the server side (PHP/Laravel 5.1). The problem is if a user logged to my site and opened it in more than one tab/window - the new window.open fire multiple time, anyone know how can I prevent it? my code look like this:

the socket listener:

socket.on('message', function (data) {
    data = JSON.parse(data);
    if(typeof data.data !== "undefined"){
        lead_data = data.data;
    }else{
        lead_data = data;
    }
    if(typeof lead_data !== "undefined" && (lead_data.event_name == "new_call" || lead_data.event_name == "new_unsaved_call")){
        if(lead_data.user_id == uid){
            window.App.openCallWindow(data);
        }
    }
});

and the openCallWindow function:

openCallWindow : function(data){
    void(0);
    var lead_id = '';
    if(data && data.lead){
        lead_id = data.lead._id;
        window.open('/leads/callLead/'+lead_id,'new_lead'+Math.floor((Math.random()*999)+1), "height=800,width=1200" );
    }else if(typeof data.phone !== "undefined"){
        window.open('/leads/callLead/?phone='+data.phone,'new_lead'+Math.floor((Math.random()*999)+1), "height=800,width=1200" );
    }else{
        window.open('/leads/callLead/'+lead_id,'new_lead'+Math.floor((Math.random()*999)+1), "height=800,width=1200" );
    }
},
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
benjah
  • 613
  • 7
  • 29

2 Answers2

1

Client side active tab solution:

You could call window.open only on, if the tab is active ( currently viewed ). This could be done like this:

function isTabActive(){
    var state; 

    if (typeof document.hidden !== "undefined") {
        state = "visibilityState";
    } else if (typeof document.mozHidden !== "undefined") {
        state = "mozVisibilityState";
    } else if (typeof document.msHidden !== "undefined") {
        state = "msVisibilityState";
    } else if (typeof document.webkitHidden !== "undefined") {
        state = "webkitVisibilityState";
    }
    return document[state] != "hidden";
}

Client sided with cookies

You could also use cookies to save if the popup is already open. Cookies can be written and read with js.

Server sided solution with socket.io

If you have user accounts use them instead of the ip! Otherwise it will be buggy for multiple users with the same ip.

var alreadySend={};
io.on('connection', function(socket)
{
   if(!alreadySend.hasOwnProperty(socket.handshake.address))
   {
      socket.emit("create popup", "popup1");
      alreadySend[socket.handshake.address]=true;
   }
});

reset with

delete alreadySend[socket.handshake.address];

Also here you can find more detailed info about getting the ip with socket.io

Community
  • 1
  • 1
zuim
  • 1,039
  • 8
  • 10
  • thank you very much for the answer mate, but I still need to open the new window even if the window isn't active. is there's a way to validate how many windows of my website opened or check if the event fired already from another place? – benjah Jun 19 '16 at 13:50
  • I don't know if that is possible, but you could use the ip or username/userid of socket.io to only send the 'message' to one connection per ip/user. The IP is in `socket.handshake.address` and you could create an object like `messageSend[ip/userName]=true/false;` and then query before sending if this ip/user already got the message. – zuim Jun 19 '16 at 14:03
  • I'm quite new to socket.io, can you please give a code example? should I add it in the socket connection handler? – benjah Jun 20 '16 at 05:16
  • I extended my answer with two more solutions and example code! – zuim Jun 20 '16 at 16:10
0

You can use state and access it through a function like

function isTabActive(){
    var state; 

    if (typeof document.hidden !== "undefined") {
        state = "visibilityState";
    } else if (typeof document.mozHidden !== "undefined") {
        state = "mozVisibilityState";
    } else if (typeof document.msHidden !== "undefined") {
        state = "msVisibilityState";
    } else if (typeof document.webkitHidden !== "undefined") {
        state = "webkitVisibilityState";
    }
    return document[state] != "hidden";
}
Radio-
  • 3,151
  • 21
  • 22
Amit
  • 1
  • 1