Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ Exposed as `eio` in the browser standalone build.
- `forceNode` (`Boolean`): Uses NodeJS implementation for websockets - even if there is a native Browser-Websocket available, which is preferred by default over the NodeJS implementation. (This is useful when using hybrid platforms like nw.js or electron) (`false`, NodeJS only)
- `localAddress` (`String`): the local IP address to connect to
- `autoUnref` (`Boolean`): whether the transport should be `unref`'d upon creation. This calls `unref` on the underlying timers and sockets so that the program is allowed to exit if they are the only timers/sockets in the event system (Node.js only)
- `useNativeTimeouts` (`Boolean`): Whether to always use the native timeouts. This allows the client to reconnect when the native timeout functions are overridden, such as when mock clocks are installed.
- **Polling-only options**
- `requestTimeout` (`Number`): Timeout for xhr-polling requests in milliseconds (`0`)
- **Websocket-only options**
Expand Down
13 changes: 8 additions & 5 deletions lib/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const debug = require("debug")("engine.io-client:socket");
const parser = require("engine.io-parser");
const parseuri = require("parseuri");
const parseqs = require("parseqs");
const { installTimeoutFunctions } = require("./timeouts");

class Socket extends Emitter {
/**
Expand Down Expand Up @@ -31,6 +32,8 @@ class Socket extends Emitter {
opts.hostname = parseuri(opts.host).host;
}

installTimeoutFunctions(this, opts);

this.secure =
null != opts.secure
? opts.secure
Expand Down Expand Up @@ -172,7 +175,7 @@ class Socket extends Emitter {
transport = "websocket";
} else if (0 === this.transports.length) {
// Emit error on next tick so it can be listened to
setTimeout(() => {
this.setTimeoutFn(() => {
this.emit("error", "No transports available");
}, 0);
return;
Expand Down Expand Up @@ -431,8 +434,8 @@ class Socket extends Emitter {
* @api private
*/
resetPingTimeout() {
clearTimeout(this.pingTimeoutTimer);
this.pingTimeoutTimer = setTimeout(() => {
this.clearTimeoutFn(this.pingTimeoutTimer);
this.pingTimeoutTimer = this.setTimeoutFn(() => {
this.onClose("ping timeout");
}, this.pingInterval + this.pingTimeout);
if (this.opts.autoUnref) {
Expand Down Expand Up @@ -609,8 +612,8 @@ class Socket extends Emitter {
debug('socket close with reason: "%s"', reason);

// clear timers
clearTimeout(this.pingIntervalTimer);
clearTimeout(this.pingTimeoutTimer);
this.clearTimeoutFn(this.pingIntervalTimer);
this.clearTimeoutFn(this.pingTimeoutTimer);

// stop event from firing again for transport
this.transport.removeAllListeners("close");
Expand Down
15 changes: 15 additions & 0 deletions lib/timeouts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const self = require("./globalThis");
// Keep a reference to the real timeout functions so they can be used when
// overridden.
const NATIVE_SET_TIMEOUT = setTimeout;
const NATIVE_CLEAR_TIMEOUT = clearTimeout;

module.exports.installTimeoutFunctions = function(obj, opts) {
if (opts.useNativeTimeouts) {
obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(self);
obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(self);
} else {
obj.setTimeoutFn = setTimeout.bind(self);
obj.clearTimeoutFn = clearTimeout.bind(self);
}
};
2 changes: 2 additions & 0 deletions lib/transport.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const parser = require("engine.io-parser");
const Emitter = require("component-emitter");
const { installTimeoutFunctions } = require("./timeouts");
const debug = require("debug")("engine.io-client:transport");

class Transport extends Emitter {
Expand All @@ -11,6 +12,7 @@ class Transport extends Emitter {
*/
constructor(opts) {
super();
installTimeoutFunctions(this, opts);

this.opts = opts;
this.query = opts.query;
Expand Down
2 changes: 1 addition & 1 deletion lib/transports/polling-jsonp.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class JSONPPolling extends Polling {
"undefined" !== typeof navigator && /gecko/i.test(navigator.userAgent);

if (isUAgecko) {
setTimeout(function() {
this.setTimeoutFn(function() {
const iframe = document.createElement("iframe");
document.body.appendChild(iframe);
document.body.removeChild(iframe);
Expand Down
6 changes: 4 additions & 2 deletions lib/transports/polling-xhr.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const Polling = require("./polling");
const Emitter = require("component-emitter");
const { pick } = require("../util");
const globalThis = require("../globalThis");
const { installTimeoutFunctions } = require("../timeouts");

const debug = require("debug")("engine.io-client:polling-xhr");

Expand Down Expand Up @@ -105,6 +106,7 @@ class Request extends Emitter {
*/
constructor(uri, opts) {
super();
installTimeoutFunctions(this, opts);
this.opts = opts;

this.method = opts.method || "GET";
Expand Down Expand Up @@ -187,7 +189,7 @@ class Request extends Emitter {
} else {
// make sure the `error` event handler that's user-set
// does not throw in the same tick and gets caught here
setTimeout(() => {
this.setTimeoutFn(() => {
this.onError(typeof xhr.status === "number" ? xhr.status : 0);
}, 0);
}
Expand All @@ -200,7 +202,7 @@ class Request extends Emitter {
// Need to defer since .create() is called directly from the constructor
// and thus the 'error' event can only be only bound *after* this exception
// occurs. Therefore, also, we cannot throw here at all.
setTimeout(() => {
this.setTimeoutFn(() => {
this.onError(e);
}, 0);
return;
Expand Down
2 changes: 1 addition & 1 deletion lib/transports/websocket-constructor.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const nextTick = (() => {
if (isPromiseAvailable) {
return cb => Promise.resolve().then(cb);
} else {
return cb => setTimeout(cb, 0);
return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
}
})();

Expand Down
2 changes: 1 addition & 1 deletion lib/transports/websocket-constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ module.exports = {
WebSocket: require("ws"),
usingBrowserWebSocket: false,
defaultBinaryType: "nodebuffer",
nextTick: process.nextTick
nextTick: (cb, _setTimeoutFn) => process.nextTick(cb)
};
2 changes: 1 addition & 1 deletion lib/transports/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class WS extends Transport {
nextTick(() => {
this.writable = true;
this.emit("drain");
});
}, this.setTimeoutFn);
}
});
}
Expand Down
Loading