Skip to content

Commit dad588f

Browse files
trentmwillisrexxars
authored andcommitted
Improve performance for large messages across many chunks (#130)
1 parent 4ad734b commit dad588f

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

lib/eventsource.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ function EventSource (url, eventSourceInitDict) {
181181
// Source/WebCore/page/EventSource.cpp
182182
var isFirst = true
183183
var buf
184+
var startingPos = 0
185+
var startingFieldLength = -1
184186
res.on('data', function (chunk) {
185187
buf = buf ? Buffer.concat([buf, chunk]) : chunk
186188
if (isFirst && hasBom(buf)) {
@@ -200,10 +202,10 @@ function EventSource (url, eventSourceInitDict) {
200202
}
201203

202204
var lineLength = -1
203-
var fieldLength = -1
205+
var fieldLength = startingFieldLength
204206
var c
205207

206-
for (var i = pos; lineLength < 0 && i < length; ++i) {
208+
for (var i = startingPos; lineLength < 0 && i < length; ++i) {
207209
c = buf[i]
208210
if (c === colon) {
209211
if (fieldLength < 0) {
@@ -218,7 +220,12 @@ function EventSource (url, eventSourceInitDict) {
218220
}
219221

220222
if (lineLength < 0) {
223+
startingPos = length - pos
224+
startingFieldLength = fieldLength
221225
break
226+
} else {
227+
startingPos = 0
228+
startingFieldLength = -1
222229
}
223230

224231
parseEventStreamLine(buf, pos, fieldLength, lineLength)

test/eventsource_test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,26 @@ describe('Parser', function () {
467467
}
468468
})
469469
})
470+
471+
it('parses a relatively huge message across many chunks efficiently', function (done) {
472+
this.timeout(1000)
473+
474+
createServer(function (err, server) {
475+
if (err) return done(err)
476+
477+
var longMessageContent = new Array(100000).join('a')
478+
var longMessage = 'data: ' + longMessageContent + '\n\n'
479+
var longMessageChunks = longMessage.match(/[\s\S]{1,10}/g) // Split the message into chunks of 10 characters
480+
server.on('request', writeEvents(longMessageChunks))
481+
482+
var es = new EventSource(server.url)
483+
484+
es.onmessage = function (m) {
485+
assert.equal(longMessageContent, m.data)
486+
server.close(done)
487+
}
488+
})
489+
})
470490
})
471491

472492
describe('HTTP Request', function () {

0 commit comments

Comments
 (0)