检查 WebSocket 服务器是否可用而不会出错

Check if a WebSocket server is available without erroring

我的网络应用程序需要定期检查服务器是否已启动。这允许用户以任一顺序启动服务器和客户端。

为此,我只是从 setTimeout 处理程序中调用 WebSocket 构造函数。

这个策略从使用的角度来看效果很好,但对我这个开发者来说很烦人,因为我在 Chrome:

中看到了很多控制台错误
remote.html:194 WebSocket connection to 'ws://localhost:8082/' failed: Connection closed before receiving a handshake response
remote.html:194 WebSocket connection to 'ws://localhost:8082/' failed: Connection closed before receiving a handshake response
remote.html:194 WebSocket connection to 'ws://localhost:8082/' failed: Connection closed before receiving a handshake response

这些并不是真正的错误,因为我的网络应用程序在服务器不可用的情况下完全没问题。它重复调用 WebSocket 构造函数 (MDN) 只是为了检查服务器是否已经启动。

有更好的方法吗?对于上下文,我的网络应用程序是在设备上运行的本机 C++ 应用程序的“远程控制”。

请注意,连接错误消息主要由浏览器本身处理,而不是 JS 运行时。

如果您想明确抑制运行时错误,可以使用 onerror 事件处理程序。 示例:

window.onerror = function(message, url, lineNumber) {
        // you can also filter out certain messages in this handler
        return true; // prevents all error messages from displaying
};

此外,考虑使用诸如设置健康检查 HTTP 端点之类的方法,而不是打开 WS 连接。

正如您的错误消息所述,您在打开后立即关闭连接,您不应该这样做,相反您可以保持一个 WS 连接打开并使用 ping/pong WebSocket 消息来检查连接是否存在,因此确保服务器也处于活动状态。如果连接关闭,您可以定期重试连接 setInterval,如果连接尝试成功,则重用先前的 WS 对象变量并使用 clearInterval.

销毁间隔

所有错误都被抑制了,但不能低于这个原因

WebSocket connection to 'ws://localhost:5000/tech-support' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

无法捕获该错误消息,它与创建 WebSocket 对象的代码异步发生。

此处有更多详细信息:

使用 SharedWorker 时会抑制错误!尝试以下操作:

main.html

<!doctype html>
<html>
  <head>
    <title>WS Test</title>
    <script type="text/javascript"> (async () => {
      
      await new Promise(r => window.addEventListener('load', r));
            
      let worker = new SharedWorker('worker.js');
      worker.port.onmessage = evt => console.log('MSG:', evt.data);
      
    })() </script>
  </head>
  <body></body>
</html>

worker.js

let ports = [];
onconnect = ({ ports: [ port ] }) => ports.push(port);

(async () => {
  
  while (true) {
    
    await new Promise(r => setTimeout(r, 1000));
    
    let ws = new WebSocket('ws://localhost:9999/');
    ws.addEventListener('error', evt => ports.forEach(port => port.postMessage('error')));
    ws.addEventListener('open', evt => ports.forEach(port => port.postMessage('open')));
    
  }
  
})();

这给我的反馈是 WebSocket 正在击中 Error,但不会在日志中产生任何额外的噪音:

(请注意,“某些消息已移至问题面板”是由于草率的不符合标准的测试 html - 如果您将此解决方案转移到您自己的代码中,它将消失!)

A SharedWorker 对任何特定选项卡都没有必要 link - 因此我看不出为什么 SharedWorker 的错误会在选项卡的错误中显示为噪音任何环境中的控制台。

Websockets 刚刚升级 HTTP/HTTPS 端点,所以你可以做一个请求并检查是否可以升级