diff --git a/reconnecting-websocket.js b/reconnecting-websocket.js index fdea720..1283920 100644 --- a/reconnecting-websocket.js +++ b/reconnecting-websocket.js @@ -125,11 +125,11 @@ reconnectDecay: 1.5, /** The maximum time in milliseconds to wait for a connection to succeed before closing and retrying. */ - timeoutInterval: 2000, + timeoutInterval: 3000, /** The maximum number of reconnection attempts to make. Unlimited if null. */ - maxReconnectAttempts: null - } + maxReconnectAttempts: 50 + }; if (!options) { options = {}; } // Overwrite and define settings with options if they exist. @@ -178,6 +178,7 @@ eventTarget.addEventListener('connecting', function(event) { self.onconnecting(event); }); eventTarget.addEventListener('message', function(event) { self.onmessage(event); }); eventTarget.addEventListener('error', function(event) { self.onerror(event); }); + eventTarget.addEventListener('maxAttemptsExceed', function(event) { self.onmaxattemptsexceed(event); }); // Expose the API required by EventTarget @@ -197,16 +198,17 @@ * @param args Object an optional object that the event will use */ function generateEvent(s, args) { - var evt = document.createEvent("CustomEvent"); - evt.initCustomEvent(s, false, false, args); - return evt; - }; + var evt = document.createEvent("CustomEvent"); + evt.initCustomEvent(s, false, false, args); + return evt; + } this.open = function (reconnectAttempt) { ws = new WebSocket(self.url, protocols || []); if (reconnectAttempt) { if (this.maxReconnectAttempts && this.reconnectAttempts > this.maxReconnectAttempts) { + eventTarget.dispatchEvent(generateEvent('maxAttemptsExceed')); return; } } else { @@ -262,11 +264,11 @@ eventTarget.dispatchEvent(generateEvent('close')); } - var timeout = self.reconnectInterval * Math.pow(self.reconnectDecay, self.reconnectAttempts); + var delay = self.reconnectInterval * Math.pow(self.reconnectDecay, self.reconnectAttempts); setTimeout(function() { self.reconnectAttempts++; self.open(true); - }, timeout > self.maxReconnectInterval ? self.maxReconnectInterval : timeout); + }, delay > self.maxReconnectInterval ? self.maxReconnectInterval : delay); } }; ws.onmessage = function(event) { @@ -283,10 +285,10 @@ } eventTarget.dispatchEvent(generateEvent('error')); }; - } + }; // Whether or not to create a websocket upon instantiation - if (this.automaticOpen == true) { + if (this.automaticOpen === true) { this.open(false); } @@ -345,6 +347,8 @@ ReconnectingWebSocket.prototype.onmessage = function(event) {}; /** An event listener to be called when an error occurs. */ ReconnectingWebSocket.prototype.onerror = function(event) {}; + /** An event listener to be called when connecting attempts exceeded */ + ReconnectingWebSocket.prototype.onmaxattemptsexceed = function(event) {}; /** * Whether all instances of ReconnectingWebSocket should log debug messages. diff --git a/reconnecting-websocket.min.js b/reconnecting-websocket.min.js index 3015099..f1091b4 100644 --- a/reconnecting-websocket.min.js +++ b/reconnecting-websocket.min.js @@ -1 +1 @@ -!function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a}); +!function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function e(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var f={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:3e3,maxReconnectAttempts:50};d||(d={});for(var g in f)"undefined"!=typeof d[g]?this[g]=d[g]:this[g]=f[g];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,i=this,j=!1,k=!1,l=document.createElement("div");l.addEventListener("open",function(a){i.onopen(a)}),l.addEventListener("close",function(a){i.onclose(a)}),l.addEventListener("connecting",function(a){i.onconnecting(a)}),l.addEventListener("message",function(a){i.onmessage(a)}),l.addEventListener("error",function(a){i.onerror(a)}),l.addEventListener("maxAttemptsExceed",function(a){i.onmaxattemptsexceed(a)}),this.addEventListener=l.addEventListener.bind(l),this.removeEventListener=l.removeEventListener.bind(l),this.dispatchEvent=l.dispatchEvent.bind(l),this.open=function(b){if(h=new WebSocket(i.url,c||[]),b){if(this.maxReconnectAttempts&&this.reconnectAttempts>this.maxReconnectAttempts)return void l.dispatchEvent(e("maxAttemptsExceed"))}else l.dispatchEvent(e("connecting")),this.reconnectAttempts=0;i.debug||a.debugAll;var d=h,f=setTimeout(function(){i.debug||a.debugAll,k=!0,d.close(),k=!1},i.timeoutInterval);h.onopen=function(c){clearTimeout(f),i.debug||a.debugAll,i.protocol=h.protocol,i.readyState=WebSocket.OPEN,i.reconnectAttempts=0;var d=e("open");d.isReconnect=b,b=!1,l.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(f),h=null,j)i.readyState=WebSocket.CLOSED,l.dispatchEvent(e("close"));else{i.readyState=WebSocket.CONNECTING;var d=e("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,l.dispatchEvent(d),b||k||(i.debug||a.debugAll,l.dispatchEvent(e("close")));var g=i.reconnectInterval*Math.pow(i.reconnectDecay,i.reconnectAttempts);setTimeout(function(){i.reconnectAttempts++,i.open(!0)},g>i.maxReconnectInterval?i.maxReconnectInterval:g)}},h.onmessage=function(b){i.debug||a.debugAll;var c=e("message");c.data=b.data,l.dispatchEvent(c)},h.onerror=function(b){i.debug||a.debugAll,l.dispatchEvent(e("error"))}},this.automaticOpen===!0&&this.open(!1),this.send=function(b){if(h)return i.debug||a.debugAll,h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),j=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}if("WebSocket"in window)return a.prototype.onopen=function(a){},a.prototype.onclose=function(a){},a.prototype.onconnecting=function(a){},a.prototype.onmessage=function(a){},a.prototype.onerror=function(a){},a.prototype.onmaxattemptsexceed=function(a){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a}); \ No newline at end of file