Comparing version 8.4.0 to 8.0.0
@@ -10,5 +10,2 @@ 'use strict'; | ||
WebSocket.WebSocket = WebSocket; | ||
WebSocket.WebSocketServer = WebSocket.Server; | ||
module.exports = WebSocket; |
@@ -33,14 +33,10 @@ 'use strict'; | ||
* @param {Object} [options] Configuration options | ||
* @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support | ||
* for, or request, a custom client window size | ||
* @param {Boolean} [options.serverNoContextTakeover=false] Request/accept | ||
* disabling of server context takeover | ||
* @param {Boolean} [options.clientNoContextTakeover=false] Advertise/ | ||
* acknowledge disabling of client context takeover | ||
* @param {Number} [options.concurrencyLimit=10] The number of concurrent | ||
* calls to zlib | ||
* @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the | ||
* use of a custom server window size | ||
* @param {Boolean} [options.serverNoContextTakeover=false] Request/accept | ||
* disabling of server context takeover | ||
* @param {Number} [options.threshold=1024] Size (in bytes) below which | ||
* messages should not be compressed if context takeover is disabled | ||
* @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support | ||
* for, or request, a custom client window size | ||
* @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on | ||
@@ -50,2 +46,6 @@ * deflate | ||
* inflate | ||
* @param {Number} [options.threshold=1024] Size (in bytes) below which | ||
* messages should not be compressed | ||
* @param {Number} [options.concurrencyLimit=10] The number of concurrent | ||
* calls to zlib | ||
* @param {Boolean} [isServer=false] Create the instance in either server or | ||
@@ -52,0 +52,0 @@ * client mode |
@@ -31,21 +31,16 @@ 'use strict'; | ||
* | ||
* @param {Object} [options] Options object | ||
* @param {String} [options.binaryType=nodebuffer] The type for binary data | ||
* @param {Object} [options.extensions] An object containing the negotiated | ||
* extensions | ||
* @param {Boolean} [options.isServer=false] Specifies whether to operate in | ||
* client or server mode | ||
* @param {Number} [options.maxPayload=0] The maximum allowed message length | ||
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or | ||
* not to skip UTF-8 validation for text and close messages | ||
* @param {String} [binaryType=nodebuffer] The type for binary data | ||
* @param {Object} [extensions] An object containing the negotiated extensions | ||
* @param {Boolean} [isServer=false] Specifies whether to operate in client or | ||
* server mode | ||
* @param {Number} [maxPayload=0] The maximum allowed message length | ||
*/ | ||
constructor(options = {}) { | ||
constructor(binaryType, extensions, isServer, maxPayload) { | ||
super(); | ||
this._binaryType = options.binaryType || BINARY_TYPES[0]; | ||
this._extensions = options.extensions || {}; | ||
this._isServer = !!options.isServer; | ||
this._maxPayload = options.maxPayload | 0; | ||
this._skipUTF8Validation = !!options.skipUTF8Validation; | ||
this._binaryType = binaryType || BINARY_TYPES[0]; | ||
this[kWebSocket] = undefined; | ||
this._extensions = extensions || {}; | ||
this._isServer = !!isServer; | ||
this._maxPayload = maxPayload | 0; | ||
@@ -421,9 +416,3 @@ this._bufferedBytes = 0; | ||
data = this.consume(this._payloadLength); | ||
if ( | ||
this._masked && | ||
(this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0 | ||
) { | ||
unmask(data, this._mask); | ||
} | ||
if (this._masked) unmask(data, this._mask); | ||
} | ||
@@ -441,3 +430,3 @@ | ||
// | ||
// This message is not compressed so its length is the sum of the payload | ||
// This message is not compressed so its lenght is the sum of the payload | ||
// length of all fragments. | ||
@@ -520,3 +509,3 @@ // | ||
if (!this._skipUTF8Validation && !isValidUTF8(buf)) { | ||
if (!isValidUTF8(buf)) { | ||
this._loop = false; | ||
@@ -576,3 +565,3 @@ return error( | ||
if (!this._skipUTF8Validation && !isValidUTF8(buf)) { | ||
if (!isValidUTF8(buf)) { | ||
return error( | ||
@@ -579,0 +568,0 @@ Error, |
@@ -14,3 +14,3 @@ /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls$" }] */ | ||
const maskBuffer = Buffer.alloc(4); | ||
const mask = Buffer.alloc(4); | ||
@@ -26,13 +26,5 @@ /** | ||
* @param {Object} [extensions] An object containing the negotiated extensions | ||
* @param {Function} [generateMask] The function used to generate the masking | ||
* key | ||
*/ | ||
constructor(socket, extensions, generateMask) { | ||
constructor(socket, extensions) { | ||
this._extensions = extensions || {}; | ||
if (generateMask) { | ||
this._generateMask = generateMask; | ||
this._maskBuffer = Buffer.alloc(4); | ||
} | ||
this._socket = socket; | ||
@@ -53,13 +45,9 @@ | ||
* @param {Object} options Options object | ||
* @param {Number} options.opcode The opcode | ||
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be | ||
* modified | ||
* @param {Boolean} [options.fin=false] Specifies whether or not to set the | ||
* FIN bit | ||
* @param {Function} [options.generateMask] The function used to generate the | ||
* masking key | ||
* @param {Boolean} [options.mask=false] Specifies whether or not to mask | ||
* `data` | ||
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking | ||
* key | ||
* @param {Number} options.opcode The opcode | ||
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be | ||
* modified | ||
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the | ||
@@ -71,22 +59,4 @@ * RSV1 bit | ||
static frame(data, options) { | ||
let mask; | ||
let merge = false; | ||
let offset = 2; | ||
let skipMasking = false; | ||
if (options.mask) { | ||
mask = options.maskBuffer || maskBuffer; | ||
if (options.generateMask) { | ||
options.generateMask(mask); | ||
} else { | ||
randomFillSync(mask, 0, 4); | ||
} | ||
skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0; | ||
if (options.readOnly && !skipMasking) merge = true; | ||
offset = 6; | ||
} | ||
const merge = options.mask && options.readOnly; | ||
let offset = options.mask ? 6 : 2; | ||
let payloadLength = data.length; | ||
@@ -112,4 +82,4 @@ | ||
} else if (payloadLength === 127) { | ||
target[2] = target[3] = 0; | ||
target.writeUIntBE(data.length, 4, 6); | ||
target.writeUInt32BE(0, 2); | ||
target.writeUInt32BE(data.length, 6); | ||
} | ||
@@ -119,2 +89,4 @@ | ||
randomFillSync(mask, 0, 4); | ||
target[1] |= 0x80; | ||
@@ -126,4 +98,2 @@ target[offset - 4] = mask[0]; | ||
if (skipMasking) return [target, data]; | ||
if (merge) { | ||
@@ -196,4 +166,2 @@ applyMask(data, mask, target, offset, data.length); | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly: false | ||
@@ -243,4 +211,2 @@ }), | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly | ||
@@ -290,4 +256,2 @@ }), | ||
mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly | ||
@@ -304,6 +268,6 @@ }), | ||
* @param {Object} options Options object | ||
* @param {Boolean} [options.compress=false] Specifies whether or not to | ||
* compress `data` | ||
* @param {Boolean} [options.binary=false] Specifies whether `data` is binary | ||
* or text | ||
* @param {Boolean} [options.compress=false] Specifies whether or not to | ||
* compress `data` | ||
* @param {Boolean} [options.fin=false] Specifies whether the fragment is the | ||
@@ -324,11 +288,3 @@ * last one | ||
this._firstFragment = false; | ||
if ( | ||
rsv1 && | ||
perMessageDeflate && | ||
perMessageDeflate.params[ | ||
perMessageDeflate._isServer | ||
? 'server_no_context_takeover' | ||
: 'client_no_context_takeover' | ||
] | ||
) { | ||
if (rsv1 && perMessageDeflate) { | ||
rsv1 = buf.length >= perMessageDeflate._threshold; | ||
@@ -350,4 +306,2 @@ } | ||
mask: options.mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly: toBuffer.readOnly | ||
@@ -368,4 +322,2 @@ }; | ||
mask: options.mask, | ||
maskBuffer: this._maskBuffer, | ||
generateMask: this._generateMask, | ||
readOnly: toBuffer.readOnly | ||
@@ -386,12 +338,8 @@ }), | ||
* @param {Number} options.opcode The opcode | ||
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be | ||
* modified | ||
* @param {Boolean} [options.fin=false] Specifies whether or not to set the | ||
* FIN bit | ||
* @param {Function} [options.generateMask] The function used to generate the | ||
* masking key | ||
* @param {Boolean} [options.mask=false] Specifies whether or not to mask | ||
* `data` | ||
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking | ||
* key | ||
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be | ||
* modified | ||
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the | ||
@@ -398,0 +346,0 @@ * RSV1 bit |
@@ -50,4 +50,19 @@ 'use strict'; | ||
function createWebSocketStream(ws, options) { | ||
let resumeOnReceiverDrain = true; | ||
let terminateOnDestroy = true; | ||
function receiverOnDrain() { | ||
if (resumeOnReceiverDrain) ws._socket.resume(); | ||
} | ||
if (ws.readyState === ws.CONNECTING) { | ||
ws.once('open', function open() { | ||
ws._receiver.removeAllListeners('drain'); | ||
ws._receiver.on('drain', receiverOnDrain); | ||
}); | ||
} else { | ||
ws._receiver.removeAllListeners('drain'); | ||
ws._receiver.on('drain', receiverOnDrain); | ||
} | ||
const duplex = new Duplex({ | ||
@@ -65,3 +80,6 @@ ...options, | ||
if (!duplex.push(data)) ws.pause(); | ||
if (!duplex.push(data)) { | ||
resumeOnReceiverDrain = false; | ||
ws._socket.pause(); | ||
} | ||
}); | ||
@@ -142,3 +160,6 @@ | ||
duplex._read = function () { | ||
if (ws.isPaused) ws.resume(); | ||
if (ws.readyState === ws.OPEN && !resumeOnReceiverDrain) { | ||
resumeOnReceiverDrain = true; | ||
if (!ws._receiver._writableState.needDrain) ws._socket.resume(); | ||
} | ||
}; | ||
@@ -145,0 +166,0 @@ |
@@ -49,4 +49,2 @@ /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls|https$" }] */ | ||
* server to use | ||
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or | ||
* not to skip UTF-8 validation for text and close messages | ||
* @param {Function} [options.verifyClient] A hook to reject connections | ||
@@ -60,3 +58,2 @@ * @param {Function} [callback] A listener for the `listening` event | ||
maxPayload: 100 * 1024 * 1024, | ||
skipUTF8Validation: false, | ||
perMessageDeflate: false, | ||
@@ -394,6 +391,3 @@ handleProtocols: null, | ||
ws.setSocket(socket, head, { | ||
maxPayload: this.options.maxPayload, | ||
skipUTF8Validation: this.options.skipUTF8Validation | ||
}); | ||
ws.setSocket(socket, head, this.options.maxPayload); | ||
@@ -400,0 +394,0 @@ if (this.clients) { |
@@ -1,3 +0,1 @@ | ||
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Readable$" }] */ | ||
'use strict'; | ||
@@ -11,3 +9,2 @@ | ||
const { randomBytes, createHash } = require('crypto'); | ||
const { Readable } = require('stream'); | ||
const { URL } = require('url'); | ||
@@ -62,3 +59,2 @@ | ||
this._extensions = {}; | ||
this._paused = false; | ||
this._protocol = ''; | ||
@@ -131,9 +127,2 @@ this._readyState = WebSocket.CONNECTING; | ||
/** | ||
* @type {Boolean} | ||
*/ | ||
get isPaused() { | ||
return this._paused; | ||
} | ||
/** | ||
* @type {Function} | ||
@@ -197,20 +186,14 @@ */ | ||
* @param {Buffer} head The first packet of the upgraded stream | ||
* @param {Object} options Options object | ||
* @param {Function} [options.generateMask] The function used to generate the | ||
* masking key | ||
* @param {Number} [options.maxPayload=0] The maximum allowed message size | ||
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or | ||
* not to skip UTF-8 validation for text and close messages | ||
* @param {Number} [maxPayload=0] The maximum allowed message size | ||
* @private | ||
*/ | ||
setSocket(socket, head, options) { | ||
const receiver = new Receiver({ | ||
binaryType: this.binaryType, | ||
extensions: this._extensions, | ||
isServer: this._isServer, | ||
maxPayload: options.maxPayload, | ||
skipUTF8Validation: options.skipUTF8Validation | ||
}); | ||
setSocket(socket, head, maxPayload) { | ||
const receiver = new Receiver( | ||
this.binaryType, | ||
this._extensions, | ||
this._isServer, | ||
maxPayload | ||
); | ||
this._sender = new Sender(socket, this._extensions, options.generateMask); | ||
this._sender = new Sender(socket, this._extensions); | ||
this._receiver = receiver; | ||
@@ -330,19 +313,2 @@ this._socket = socket; | ||
/** | ||
* Pause the socket. | ||
* | ||
* @public | ||
*/ | ||
pause() { | ||
if ( | ||
this.readyState === WebSocket.CONNECTING || | ||
this.readyState === WebSocket.CLOSED | ||
) { | ||
return; | ||
} | ||
this._paused = true; | ||
this._socket.pause(); | ||
} | ||
/** | ||
* Send a ping. | ||
@@ -412,19 +378,2 @@ * | ||
/** | ||
* Resume the socket. | ||
* | ||
* @public | ||
*/ | ||
resume() { | ||
if ( | ||
this.readyState === WebSocket.CONNECTING || | ||
this.readyState === WebSocket.CLOSED | ||
) { | ||
return; | ||
} | ||
this._paused = false; | ||
if (!this._receiver._writableState.needDrain) this._socket.resume(); | ||
} | ||
/** | ||
* Send a data message. | ||
@@ -434,6 +383,6 @@ * | ||
* @param {Object} [options] Options object | ||
* @param {Boolean} [options.compress] Specifies whether or not to compress | ||
* `data` | ||
* @param {Boolean} [options.binary] Specifies whether `data` is binary or | ||
* text | ||
* @param {Boolean} [options.compress] Specifies whether or not to compress | ||
* `data` | ||
* @param {Boolean} [options.fin=true] Specifies whether the fragment is the | ||
@@ -572,3 +521,2 @@ * last one | ||
'extensions', | ||
'isPaused', | ||
'protocol', | ||
@@ -624,20 +572,16 @@ 'readyState', | ||
* @param {Object} [options] Connection options | ||
* @param {Boolean} [options.followRedirects=false] Whether or not to follow | ||
* redirects | ||
* @param {Function} [options.generateMask] The function used to generate the | ||
* masking key | ||
* @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable | ||
* permessage-deflate | ||
* @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the | ||
* handshake request | ||
* @param {Number} [options.protocolVersion=13] Value of the | ||
* `Sec-WebSocket-Version` header | ||
* @param {String} [options.origin] Value of the `Origin` or | ||
* `Sec-WebSocket-Origin` header | ||
* @param {Number} [options.maxPayload=104857600] The maximum allowed message | ||
* size | ||
* @param {Boolean} [options.followRedirects=false] Whether or not to follow | ||
* redirects | ||
* @param {Number} [options.maxRedirects=10] The maximum number of redirects | ||
* allowed | ||
* @param {String} [options.origin] Value of the `Origin` or | ||
* `Sec-WebSocket-Origin` header | ||
* @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable | ||
* permessage-deflate | ||
* @param {Number} [options.protocolVersion=13] Value of the | ||
* `Sec-WebSocket-Version` header | ||
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or | ||
* not to skip UTF-8 validation for text and close messages | ||
* @private | ||
@@ -649,3 +593,2 @@ */ | ||
maxPayload: 100 * 1024 * 1024, | ||
skipUTF8Validation: false, | ||
perMessageDeflate: true, | ||
@@ -690,22 +633,15 @@ followRedirects: false, | ||
const isUnixSocket = parsedUrl.protocol === 'ws+unix:'; | ||
let invalidURLMessage; | ||
if (parsedUrl.protocol !== 'ws:' && !isSecure && !isUnixSocket) { | ||
invalidURLMessage = | ||
'The URL\'s protocol must be one of "ws:", "wss:", or "ws+unix:"'; | ||
} else if (isUnixSocket && !parsedUrl.pathname) { | ||
invalidURLMessage = "The URL's pathname is empty"; | ||
} else if (parsedUrl.hash) { | ||
invalidURLMessage = 'The URL contains a fragment identifier'; | ||
throw new SyntaxError( | ||
'The URL\'s protocol must be one of "ws:", "wss:", or "ws+unix:"' | ||
); | ||
} | ||
if (invalidURLMessage) { | ||
const err = new SyntaxError(invalidURLMessage); | ||
if (isUnixSocket && !parsedUrl.pathname) { | ||
throw new SyntaxError("The URL's pathname is empty"); | ||
} | ||
if (websocket._redirects === 0) { | ||
throw err; | ||
} else { | ||
emitErrorAndClose(websocket, err); | ||
return; | ||
} | ||
if (parsedUrl.hash) { | ||
throw new SyntaxError('The URL contains a fragment identifier'); | ||
} | ||
@@ -792,3 +728,5 @@ | ||
req = websocket._req = null; | ||
emitErrorAndClose(websocket, err); | ||
websocket._readyState = WebSocket.CLOSING; | ||
websocket.emit('error', err); | ||
websocket.emitClose(); | ||
}); | ||
@@ -813,12 +751,4 @@ | ||
let addr; | ||
const addr = new URL(location, address); | ||
try { | ||
addr = new URL(location, address); | ||
} catch (e) { | ||
const err = new SyntaxError(`Invalid URL: ${location}`); | ||
emitErrorAndClose(websocket, err); | ||
return; | ||
} | ||
initAsClient(websocket, addr, protocols, options); | ||
@@ -857,3 +787,3 @@ } else if (!websocket.emit('unexpected-response', req, res)) { | ||
if (serverProt !== undefined) { | ||
if (serverProt) { | ||
if (!protocolSet.size) { | ||
@@ -919,7 +849,3 @@ protError = 'Server sent a subprotocol but none was requested'; | ||
websocket.setSocket(socket, head, { | ||
generateMask: opts.generateMask, | ||
maxPayload: opts.maxPayload, | ||
skipUTF8Validation: opts.skipUTF8Validation | ||
}); | ||
websocket.setSocket(socket, head, opts.maxPayload); | ||
}); | ||
@@ -929,15 +855,2 @@ } | ||
/** | ||
* Emit the `'error'` and `'close'` event. | ||
* | ||
* @param {WebSocket} websocket The WebSocket instance | ||
* @param {Error} The error to emit | ||
* @private | ||
*/ | ||
function emitErrorAndClose(websocket, err) { | ||
websocket._readyState = WebSocket.CLOSING; | ||
websocket.emit('error', err); | ||
websocket.emitClose(); | ||
} | ||
/** | ||
* Create a `net.Socket` and initiate a connection. | ||
@@ -1049,2 +962,5 @@ * | ||
websocket._socket.removeListener('data', socketOnData); | ||
websocket._socket.resume(); | ||
websocket._closeFrameReceived = true; | ||
@@ -1054,7 +970,2 @@ websocket._closeMessage = reason; | ||
if (websocket._socket[kWebSocket] === undefined) return; | ||
websocket._socket.removeListener('data', socketOnData); | ||
process.nextTick(resume, websocket._socket); | ||
if (code === 1005) websocket.close(); | ||
@@ -1070,5 +981,3 @@ else websocket.close(code, reason); | ||
function receiverOnDrain() { | ||
const websocket = this[kWebSocket]; | ||
if (!websocket.isPaused) websocket._socket.resume(); | ||
this[kWebSocket]._socket.resume(); | ||
} | ||
@@ -1085,14 +994,6 @@ | ||
if (websocket._socket[kWebSocket] !== undefined) { | ||
websocket._socket.removeListener('data', socketOnData); | ||
websocket._socket.removeListener('data', socketOnData); | ||
websocket._socket.resume(); | ||
// | ||
// On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See | ||
// https://github.com/websockets/ws/issues/1940. | ||
// | ||
process.nextTick(resume, websocket._socket); | ||
websocket.close(err[kStatusCode]); | ||
} | ||
websocket.close(err[kStatusCode]); | ||
websocket.emit('error', err); | ||
@@ -1145,12 +1046,2 @@ } | ||
/** | ||
* Resume a readable stream | ||
* | ||
* @param {Readable} stream The readable stream | ||
* @private | ||
*/ | ||
function resume(stream) { | ||
stream.resume(); | ||
} | ||
/** | ||
* The listener of the `net.Socket` `'close'` event. | ||
@@ -1164,3 +1055,2 @@ * | ||
this.removeListener('close', socketOnClose); | ||
this.removeListener('data', socketOnData); | ||
this.removeListener('end', socketOnEnd); | ||
@@ -1170,4 +1060,2 @@ | ||
let chunk; | ||
// | ||
@@ -1180,15 +1068,9 @@ // The close frame might not have been received or the `'end'` event emitted, | ||
// will return `null`. If instead, the socket is paused, any possible buffered | ||
// data will be read as a single chunk. | ||
// data will be read as a single chunk and emitted synchronously in a single | ||
// `'data'` event. | ||
// | ||
if ( | ||
!this._readableState.endEmitted && | ||
!websocket._closeFrameReceived && | ||
!websocket._receiver._writableState.errorEmitted && | ||
(chunk = websocket._socket.read()) !== null | ||
) { | ||
websocket._receiver.write(chunk); | ||
} | ||
websocket._socket.read(); | ||
websocket._receiver.end(); | ||
this.removeListener('data', socketOnData); | ||
this[kWebSocket] = undefined; | ||
@@ -1195,0 +1077,0 @@ |
{ | ||
"name": "ws", | ||
"version": "8.4.0", | ||
"version": "8.0.0", | ||
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js", | ||
@@ -53,5 +53,5 @@ "keywords": [ | ||
"bufferutil": "^4.0.1", | ||
"eslint": "^8.0.0", | ||
"eslint": "^7.2.0", | ||
"eslint-config-prettier": "^8.1.0", | ||
"eslint-plugin-prettier": "^4.0.0", | ||
"eslint-plugin-prettier": "^3.0.1", | ||
"mocha": "^8.4.0", | ||
@@ -58,0 +58,0 @@ "nyc": "^15.0.0", |
# ws: a Node.js WebSocket library | ||
[![Version npm](https://img.shields.io/npm/v/ws.svg?logo=npm)](https://www.npmjs.com/package/ws) | ||
[![CI](https://img.shields.io/github/workflow/status/websockets/ws/CI/master?label=CI&logo=github)](https://github.com/websockets/ws/actions?query=workflow%3ACI+branch%3Amaster) | ||
[![Build](https://img.shields.io/github/workflow/status/websockets/ws/CI/master?label=build&logo=github)](https://github.com/websockets/ws/actions?query=workflow%3ACI+branch%3Amaster) | ||
[![Windows x86 Build](https://img.shields.io/appveyor/ci/lpinca/ws/master.svg?logo=appveyor)](https://ci.appveyor.com/project/lpinca/ws) | ||
[![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg?logo=coveralls)](https://coveralls.io/github/websockets/ws) | ||
@@ -121,3 +122,3 @@ | ||
threshold: 1024 // Size (in bytes) below which messages | ||
// should not be compressed if context takeover is disabled. | ||
// should not be compressed. | ||
} | ||
@@ -152,4 +153,4 @@ }); | ||
ws.on('message', function message(data) { | ||
console.log('received: %s', data); | ||
ws.on('message', function incoming(message) { | ||
console.log('received: %s', message); | ||
}); | ||
@@ -184,4 +185,4 @@ ``` | ||
wss.on('connection', function connection(ws) { | ||
ws.on('message', function message(data) { | ||
console.log('received: %s', data); | ||
ws.on('message', function incoming(message) { | ||
console.log('received: %s', message); | ||
}); | ||
@@ -207,4 +208,4 @@ | ||
wss.on('connection', function connection(ws) { | ||
ws.on('message', function message(data) { | ||
console.log('received: %s', data); | ||
ws.on('message', function incoming(message) { | ||
console.log('received: %s', message); | ||
}); | ||
@@ -266,4 +267,4 @@ | ||
wss.on('connection', function connection(ws, request, client) { | ||
ws.on('message', function message(data) { | ||
console.log(`Received message ${data} from user ${client}`); | ||
ws.on('message', function message(msg) { | ||
console.log(`Received message ${msg} from user ${client}`); | ||
}); | ||
@@ -274,3 +275,3 @@ }); | ||
// This function is not defined on purpose. Implement it with your own logic. | ||
authenticate(request, function next(err, client) { | ||
authenticate(request, (err, client) => { | ||
if (err || !client) { | ||
@@ -304,3 +305,3 @@ socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n'); | ||
wss.on('connection', function connection(ws) { | ||
ws.on('message', function message(data, isBinary) { | ||
ws.on('message', function incoming(data, isBinary) { | ||
wss.clients.forEach(function each(client) { | ||
@@ -324,3 +325,3 @@ if (client.readyState === WebSocket.OPEN) { | ||
wss.on('connection', function connection(ws) { | ||
ws.on('message', function message(data, isBinary) { | ||
ws.on('message', function incoming(data, isBinary) { | ||
wss.clients.forEach(function each(client) { | ||
@@ -353,3 +354,3 @@ if (client !== ws && client.readyState === WebSocket.OPEN) { | ||
ws.on('message', function message(data) { | ||
ws.on('message', function incoming(data) { | ||
console.log(`Roundtrip time: ${Date.now() - data} ms`); | ||
@@ -422,2 +423,4 @@ | ||
function noop() {} | ||
function heartbeat() { | ||
@@ -439,3 +442,3 @@ this.isAlive = true; | ||
ws.isAlive = false; | ||
ws.ping(); | ||
ws.ping(noop); | ||
}); | ||
@@ -442,0 +445,0 @@ }, 30000); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
497
124665
3632