From 96c9b3deddf56cacb2d756aaa918071e03cdbc42 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Wed, 24 Apr 2024 09:42:40 -0400 Subject: [PATCH] [major] Flip the default value of `allowSynchronousEvents` (#2221) Flip the default value of the `allowSynchronousEvents` option to `true`. Refs: https://github.com/websockets/ws/pull/2218 --- doc/ws.md | 8 +++---- lib/receiver.js | 7 ++++-- lib/websocket-server.js | 4 ++-- lib/websocket.js | 4 ++-- test/receiver.test.js | 47 ++++++----------------------------------- 5 files changed, 19 insertions(+), 51 deletions(-) diff --git a/doc/ws.md b/doc/ws.md index 017087f5f..1189fd02a 100644 --- a/doc/ws.md +++ b/doc/ws.md @@ -76,8 +76,8 @@ This class represents a WebSocket server. It extends the `EventEmitter`. in response to a ping. Defaults to `true`. - `allowSynchronousEvents` {Boolean} Specifies whether any of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple times in the same - tick. To improve compatibility with the WHATWG standard, the default value - is `false`. Setting it to `true` improves performance slightly. + tick. Defaults to `true`. Setting it to `false` improves compatibility with + the WHATWG standardbut may negatively impact performance. - `backlog` {Number} The maximum length of the queue of pending connections. - `clientTracking` {Boolean} Specifies whether or not to track clients. - `handleProtocols` {Function} A function which can be used to handle the @@ -302,8 +302,8 @@ This class represents a WebSocket. It extends the `EventEmitter`. in response to a ping. Defaults to `true`. - `allowSynchronousEvents` {Boolean} Specifies whether any of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple times in the same - tick. To improve compatibility with the WHATWG standard, the default value - is `false`. Setting it to `true` improves performance slightly. + tick. Defaults to `true`. Setting it to `false` improves compatibility with + the WHATWG standardbut may negatively impact performance. - `finishRequest` {Function} A function which can be used to customize the headers of each HTTP request before it is sent. See description below. - `followRedirects` {Boolean} Whether or not to follow redirects. Defaults to diff --git a/lib/receiver.js b/lib/receiver.js index 4515e6887..70dfd9933 100644 --- a/lib/receiver.js +++ b/lib/receiver.js @@ -32,7 +32,7 @@ class Receiver extends Writable { * Creates a Receiver instance. * * @param {Object} [options] Options object - * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted * multiple times in the same tick * @param {String} [options.binaryType=nodebuffer] The type for binary data @@ -47,7 +47,10 @@ class Receiver extends Writable { constructor(options = {}) { super(); - this._allowSynchronousEvents = !!options.allowSynchronousEvents; + this._allowSynchronousEvents = + options.allowSynchronousEvents !== undefined + ? options.allowSynchronousEvents + : true; this._binaryType = options.binaryType || BINARY_TYPES[0]; this._extensions = options.extensions || {}; this._isServer = !!options.isServer; diff --git a/lib/websocket-server.js b/lib/websocket-server.js index 4873ad9fb..40980f6e9 100644 --- a/lib/websocket-server.js +++ b/lib/websocket-server.js @@ -29,7 +29,7 @@ class WebSocketServer extends EventEmitter { * Create a `WebSocketServer` instance. * * @param {Object} options Configuration options - * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted * multiple times in the same tick * @param {Boolean} [options.autoPong=true] Specifies whether or not to @@ -60,7 +60,7 @@ class WebSocketServer extends EventEmitter { super(); options = { - allowSynchronousEvents: false, + allowSynchronousEvents: true, autoPong: true, maxPayload: 100 * 1024 * 1024, skipUTF8Validation: false, diff --git a/lib/websocket.js b/lib/websocket.js index 56d6c6fe3..709ad825a 100644 --- a/lib/websocket.js +++ b/lib/websocket.js @@ -623,7 +623,7 @@ module.exports = WebSocket; * @param {(String|URL)} address The URL to which to connect * @param {Array} protocols The subprotocols * @param {Object} [options] Connection options - * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether any + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple * times in the same tick * @param {Boolean} [options.autoPong=true] Specifies whether or not to @@ -652,7 +652,7 @@ module.exports = WebSocket; */ function initAsClient(websocket, address, protocols, options) { const opts = { - allowSynchronousEvents: false, + allowSynchronousEvents: true, autoPong: true, protocolVersion: protocolVersions[1], maxPayload: 100 * 1024 * 1024, diff --git a/test/receiver.test.js b/test/receiver.test.js index f3a0fa645..88a6326d1 100644 --- a/test/receiver.test.js +++ b/test/receiver.test.js @@ -443,7 +443,7 @@ describe('Receiver', () => { buf[i + 1] = 0x00; } - const receiver = new Receiver({ allowSynchronousEvents: true }); + const receiver = new Receiver(); let counter = 0; receiver.on('message', (data, isBinary) => { @@ -1085,7 +1085,7 @@ describe('Receiver', () => { receiver.write(Buffer.from([0x88, 0x03, 0x03, 0xe8, 0xf8])); }); - it('emits at most one event per event loop iteration', (done) => { + it('honors the `allowSynchronousEvents` option', (done) => { const actual = []; const expected = [ '1', @@ -1121,7 +1121,7 @@ describe('Receiver', () => { }); } - const receiver = new Receiver(); + const receiver = new Receiver({ allowSynchronousEvents: false }); receiver.on('message', listener); receiver.on('ping', listener); @@ -1156,43 +1156,8 @@ describe('Receiver', () => { done(); }); - receiver.write(Buffer.from('82008200', 'hex')); - }); - - it('honors the `allowSynchronousEvents` option', (done) => { - const actual = []; - const expected = [ - '1', - '2', - '3', - '4', - 'microtask 1', - 'microtask 2', - 'microtask 3', - 'microtask 4' - ]; - - function listener(data) { - const message = data.toString(); - actual.push(message); - - // `queueMicrotask()` is not available in Node.js < 11. - Promise.resolve().then(() => { - actual.push(`microtask ${message}`); - - if (actual.length === 8) { - assert.deepStrictEqual(actual, expected); - done(); - } - }); - } - - const receiver = new Receiver({ allowSynchronousEvents: true }); - - receiver.on('message', listener); - receiver.on('ping', listener); - receiver.on('pong', listener); - - receiver.write(Buffer.from('8101318901328a0133810134', 'hex')); + setImmediate(() => { + receiver.write(Buffer.from('82008200', 'hex')); + }); }); });