diff --git a/sockets.js b/sockets.js index 966070f04cb1e..3603d4290c2ae 100644 --- a/sockets.js +++ b/sockets.js @@ -437,24 +437,28 @@ class GoWorker extends EventEmitter { this.connection = connection; this.connection.setEncoding('utf8'); this.connection.on('data', /** @param {string} data */ data => { - if (!data.endsWith(DELIM)) { - // The child process sent us a message that's too long for the - // TCP connection to handle receiving all at once. Buffer. + let idx = data.lastIndexOf(DELIM); + if (idx < 0) { + // Very long message... this.ibuf += data; return; } - let message = (this.ibuf + data).slice(0, -1); + // Because of how Node handles TCP connections, we can + // receive any number of messages, and they may not + // be guaranteed to be complete. + let messages = this.ibuf; this.ibuf = ''; - - // FIXME: certain client messages are screwing with Go's JSON - // marshaller! Better not be a SockJS bug. - if (message.endsWith('\uFFFD')) { - Monitor.log(`Sockets: received a message from the client with malformed codepoints: ${message}`); - message = message.slice(0, -1); + if (idx === data.length - 1) { + messages += data.slice(0, -1); + } else { + messages += data.slice(0, idx); + this.ibuf += data.slice(idx + 1); } - this.emit('message', JSON.parse(message)); + for (let message of messages.split(DELIM)) { + this.emit('message', JSON.parse(message)); + } }); this.connection.on('error', () => {}); this.connection.once('listening', () => this.emit('listening'));