Skip to content

Commit a63172d

Browse files
trentmwillissdemontfort
authored andcommitted
Improve performance for large messages across many chunks (EventSource#130)
1 parent 1738ab6 commit a63172d

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
@@ -220,6 +220,8 @@ function EventSource (url, eventSourceInitDict) {
220220
// Source/WebCore/page/EventSource.cpp
221221
var isFirst = true
222222
var buf
223+
var startingPos = 0
224+
var startingFieldLength = -1
223225
res.on('data', function (chunk) {
224226
buf = buf ? Buffer.concat([buf, chunk]) : chunk
225227
if (isFirst && hasBom(buf)) {
@@ -239,10 +241,10 @@ function EventSource (url, eventSourceInitDict) {
239241
}
240242

241243
var lineLength = -1
242-
var fieldLength = -1
244+
var fieldLength = startingFieldLength
243245
var c
244246

245-
for (var i = pos; lineLength < 0 && i < length; ++i) {
247+
for (var i = startingPos; lineLength < 0 && i < length; ++i) {
246248
c = buf[i]
247249
if (c === colon) {
248250
if (fieldLength < 0) {
@@ -257,7 +259,12 @@ function EventSource (url, eventSourceInitDict) {
257259
}
258260

259261
if (lineLength < 0) {
262+
startingPos = length - pos
263+
startingFieldLength = fieldLength
260264
break
265+
} else {
266+
startingPos = 0
267+
startingFieldLength = -1
261268
}
262269

263270
parseEventStreamLine(buf, pos, fieldLength, lineLength)

test/eventsource_test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,26 @@ describe('Parser', function () {
515515
}
516516
})
517517
})
518+
519+
it('parses a relatively huge message across many chunks efficiently', function (done) {
520+
this.timeout(1000)
521+
522+
createServer(function (err, server) {
523+
if (err) return done(err)
524+
525+
var longMessageContent = new Array(100000).join('a')
526+
var longMessage = 'data: ' + longMessageContent + '\n\n'
527+
var longMessageChunks = longMessage.match(/[\s\S]{1,10}/g) // Split the message into chunks of 10 characters
528+
server.on('request', writeEvents(longMessageChunks))
529+
530+
var es = new EventSource(server.url)
531+
532+
es.onmessage = function (m) {
533+
assert.equal(longMessageContent, m.data)
534+
server.close(done)
535+
}
536+
})
537+
})
518538
})
519539

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

0 commit comments

Comments
 (0)