gpt4 book ai didi

javascript - WebSocket 连接超时

转载 作者:可可西里 更新时间:2023-11-01 02:10:58 24 4
gpt4 key购买 nike

我正在尝试实现故障安全 websocket 包装器。我遇到的问题是处理超时错误。逻辑应该是:如果套接字在 $timeoutInMiliseconds 期间没有打开 - 它必须关闭并重新打开 $N 次。

我正在写这样的东西。

var maxReconects = 0;
var ws = new WebSocket(url);
var onCloseHandler = function() {
if ( maxReconects < N ) {
maxReconects++;
// construct new Websocket
....
}
};
ws.onclose = onCloseHandler;
var timeout = setTimeout(function() {
console.log("Socket connection timeout",ws.readyState);
timedOut = true;
ws.close(); <--- ws.readyState is 0 here
timedOut = false;
},timeoutInMiliseconds);

但问题是正确处理超时 websockets - 如果我试图关闭未连接的套接字,我会在 chrome 中收到警告:

“与“ws://127.0.0.1:9010/timeout”的 WebSocket 连接失败:WebSocket 在建立连接之前关闭。”

而且我不知道如何避免它 - ws 接口(interface)没有中止功能。

我尝试过的另一种方法是如果套接字未连接则在超时时不关闭套接字,而只是将其标记为未使用更多并在它收到多个 readyState 时关闭它 - 但它可能会产生泄漏,并因此而变得复杂简单的任务。

最佳答案

我编写了以下代码用于打开带有超时和重试的 websocket 故障保护,请参阅代码中的注释以了解更多详细信息。

用法 - 打开一个具有 5000 毫秒超时和 10 次重试(最多)的 websocket:

initWebsocket('ws:\\localhost:8090', null, 5000, 10).then(function(socket){
console.log('socket initialized!');
//do something with socket...

//if you want to use the socket later again and assure that it is still open:
initWebsocket('ws:\\localhost:8090', socket, 5000, 10).then(function(socket){
//if socket is still open, you are using the same "socket" object here
//if socket was closed, you are using a new opened "socket" object
}

}, function(){
console.log('init of socket failed!');
});

方法 initWebsocket() 在库或类似库中定义的某处:

/**
* inits a websocket by a given url, returned promise resolves with initialized websocket, rejects after failure/timeout.
*
* @param url the websocket url to init
* @param existingWebsocket if passed and this passed websocket is already open, this existingWebsocket is resolved, no additional websocket is opened
* @param timeoutMs the timeout in milliseconds for opening the websocket
* @param numberOfRetries the number of times initializing the socket should be retried, if not specified or 0, no retries are made
* and a failure/timeout causes rejection of the returned promise
* @return {Promise}
*/
function initWebsocket(url, existingWebsocket, timeoutMs, numberOfRetries) {
timeoutMs = timeoutMs ? timeoutMs : 1500;
numberOfRetries = numberOfRetries ? numberOfRetries : 0;
var hasReturned = false;
var promise = new Promise((resolve, reject) => {
setTimeout(function () {
if(!hasReturned) {
console.info('opening websocket timed out: ' + url);
rejectInternal();
}
}, timeoutMs);
if (!existingWebsocket || existingWebsocket.readyState != existingWebsocket.OPEN) {
if (existingWebsocket) {
existingWebsocket.close();
}
var websocket = new WebSocket(url);
websocket.onopen = function () {
if(hasReturned) {
websocket.close();
} else {
console.info('websocket to opened! url: ' + url);
resolve(websocket);
}
};
websocket.onclose = function () {
console.info('websocket closed! url: ' + url);
rejectInternal();
};
websocket.onerror = function () {
console.info('websocket error! url: ' + url);
rejectInternal();
};
} else {
resolve(existingWebsocket);
}

function rejectInternal() {
if(numberOfRetries <= 0) {
reject();
} else if(!hasReturned) {
hasReturned = true;
console.info('retrying connection to websocket! url: ' + url + ', remaining retries: ' + (numberOfRetries-1));
initWebsocket(url, null, timeoutMs, numberOfRetries-1).then(resolve, reject);
}
}
});
promise.then(function () {hasReturned = true;}, function () {hasReturned = true;});
return promise;
};

更好的解决方案是将功能封装在自己的类 FailsafeWebsocket 或其他任何类中。然而,这个解决方案在我的项目中已经足够了 - 也许它也可以帮助其他人。

关于javascript - WebSocket 连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29881957/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com