检查 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 端点,所以你可以做一个请求并检查是否可以升级
我的网络应用程序需要定期检查服务器是否已启动。这允许用户以任一顺序启动服务器和客户端。
为此,我只是从 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 端点,所以你可以做一个请求并检查是否可以升级