如果用户“拔掉插头”并关闭计算机,是否会触发任何窗口事件?

IT技术 javascript html reactjs
2021-05-12 16:20:21

我有一个网站,我只希望客户端一次能够有 1 个 WebSocket 连接(当他们打开另一个选项卡而已经有另一个连接显示时,我向他们显示错误)。

我正在开发一个客户端解决方案,在请求连接时将本地存储中的标志更新为 true(如果标志已经为 true,则不会请求),然后我侦听beforeunload事件并设置本地存储标志如果该选项卡具有打开的连接,则为 false。

这似乎工作得很好,除了当用户突然关闭他们的计算机并且因此 beforeunload 永远不会触发的边缘情况,所以当他们重新打开他们的计算机时,本地存储标志被卡在 true 并且他们被卡住无法在任何选项卡中连接。

是否有在关闭之前调用的事件,我可以将本地存储标志设置为 false?

如果没有,客户端是否有另一种解决方案来跟踪它在所有选项卡上只有 1 个 WebSocket 连接,因此如果已经有一个连接,它可以阻止连接?

window.addEventListener('beforeunload', this.setFlagToFalse);
1个回答

正如 Jaromanda 的评论中正确指出的那样,没有电源的计算机无法向浏览器发出事件(它甚至不再存在......)。

但是,解决根本问题的一种方法是侦听存储事件。

当其他窗口对此存储进行任何修改时,此事件将在共享同一存储区域的所有 Windows 中触发。

因此,我们可以将其用作几乎实时地在来自同一域的 Windows 之间进行通信的一种方式这意味着您不必让您的标志保持最新,您现在可以直接知道其他窗口是否已经处于活动状态。

这是一个基本的实现。我会让您享受使其更适合您的需求的乐趣。

let alone = true; // a flag to know if we are alone
onstorage = e => { // listen to the storage event
  if(e.key === 'am_I_alone') {
    if(e.newValue === 'just checking') { // someone else is asking for permission
      localStorage.am_I_alone = 'false'; // refuse
    }
    else if(e.newValue === 'false') { // we've been refused access
      alone = false;
    }
  }
};

localStorage.am_I_alone = 'just checking'; // trigger the event on the other Windows

setTimeout(()=>{ // let them a little time to answer
  if(alone) { // no response, we're good to go
    // so the next one can trigger the event
    localStorage.am_I_alone = "true";
    startWebSocket();
  }
  else { // we've been rejected...
    error();
  }
}, 500);

现场直播