【问题标题】:window.open on real time event (using socket.io) when my site open in more then one window当我的网站在多个窗口中打开时,在实时事件中打开 window.open(使用 socket.io)
【发布时间】:2016-10-20 19:57:54
【问题描述】:

我的网站中有一个实时功能,可以打开服务器端触发的 socket.io 事件的新窗口(PHP/Laravel 5.1)。 问题是如果用户登录到我的网站并在多个选项卡/窗口中打开它 - 新的 window.open 多次开火,有谁知道我该如何防止它? 我的代码如下所示:

套接字监听器:

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);
        }
    }
});

openCallWindow 函数:

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" );
    }
},

【问题讨论】:

    标签: javascript socket.io dom-events


    【解决方案1】:

    客户端活动标签解决方案:

    如果选项卡处于活动状态(当前已查看),您只能调用 window.open。 这可以像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";
    }
    

    客户端使用 cookie

    如果弹出窗口已经打开,您也可以使用 cookie 进行保存。 可以用js读写cookies。

    使用 socket.io 的服务器端解决方案

    如果您有用户帐户,请使用它们而不是 ip!否则,对于具有相同 ip 的多个用户来说,这将是错误的。

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

    重置
    delete alreadySend[socket.handshake.address];
    

    另外here你可以找到更多关于通过socket.io获取ip的详细信息

    【讨论】:

    • 非常感谢您的回答,但是即使窗口不活动,我仍然需要打开新窗口。有没有办法验证我的网站打开了多少个窗口或检查事件是否已经从另一个地方触发?
    • 我不知道这是否可能,但您可以使用 socket.io 的 ip 或用户名/用户 ID 仅将“消息”发送到每个 ip/用户的一个连接。 IP 在socket.handshake.address 中,您可以创建一个类似messageSend[ip/userName]=true/false; 的对象,然后在发送前查询此IP/用户是否已经收到消息。
    • 我对socket.io很陌生,你能举个代码例子吗?我应该将它添加到套接字连接处理程序中吗?
    • 我用另外两个解决方案和示例代码扩展了我的答案!
    【解决方案2】:

    你可以使用状态并通过像

    这样的函数来访问它
    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";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 2015-09-16
      • 2011-01-17
      • 2016-03-28
      相关资源
      最近更新 更多