2015-04-26 19 views
10

Próbuję zaimplementować bezpieczną wtyczkę websocket. A problem, który mam, dotyczy błędów przekroczenia limitu czasu. Logika powinna brzmieć: jeśli gniazdo nie zostanie otwarte podczas $ timeoutInMiliseconds - musi zostać zamknięte i ponownie otwarte $ N razy.Limit czasu oczekiwania na połączenie z siecią WebSocket

Piszę coś takiego.

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

Ale problem jest obsługa limitu czasu WebSockets właściwą drogę - jeśli próbuję zamknąć gniazdo nonconnected I otrzymują ostrzeżenia w Chrome:

„połączenie websocket do„WS: //127.0.0.1: 9010/timeout 'failed: WebSocket jest zamknięty przed ustanowieniem połączenia. "

I nie mam pojęcia, jak tego uniknąć - interfejs ws nie ma funkcji przerywania.

Innym podejściem, którego próbowałem, nie jest zamykanie gniazda po przekroczeniu limitu czasu, jeśli jest niepodłączony, ale po prostu oznacz go jako nieużywany więcej i zamknij go, jeśli otrzymuje readyState więcej niż jeden - ale może powodować potencjalne przecieki i skomplikować dla takie proste zadanie.

Odpowiedz

2

Twoja zmienna timeout jest przypisana do funkcji setTimeout(..., która jest wywoływana leksykalnie. Do czasu, gdy twój kod dotrze do var onCloseHander = ..., twoja funkcja timeout została już wywołana.

Rozwiązanie to jest, aby makeTimeout funkcję:

var makeTimeout = function (timeoutInMiliseconds) { 
    return window.setTimeout(function() { 
     // do stuff 
    }, timeoutInMiliseconds) 
}; 

var timeoutId = makeTimeout(100) wywoła funkcję setTimeout i ustawić timeoutId jako wartość identyfikatora limitu czasu. Jeśli chcesz anulować ten limit czasu, można to zrobić, wywołując window.clearTimeout(timeoutId).

Powiązane problemy