@@ -17,16 +17,35 @@ function sleep(delay) {
17
17
return new Promise ( ( resolve ) => setTimeout ( resolve , delay ) ) ;
18
18
}
19
19
20
+ function createWebSocket ( url ) {
21
+ const socket = new WebSocket ( url ) ;
22
+ socket . _eventBuffer = { } ;
23
+ socket . _pendingPromises = { } ;
24
+
25
+ for ( const eventType of [ "open" , "close" , "message" ] ) {
26
+ socket . _eventBuffer [ eventType ] = [ ] ;
27
+ socket . _pendingPromises [ eventType ] = [ ] ;
28
+
29
+ socket . addEventListener ( eventType , ( event ) => {
30
+ if ( socket . _pendingPromises [ eventType ] . length ) {
31
+ socket . _pendingPromises [ eventType ] . shift ( ) ( event ) ;
32
+ } else {
33
+ socket . _eventBuffer [ eventType ] . push ( event ) ;
34
+ }
35
+ } ) ;
36
+ }
37
+
38
+ return socket ;
39
+ }
40
+
20
41
function waitFor ( socket , eventType ) {
21
- return new Promise ( ( resolve ) => {
22
- socket . addEventListener (
23
- eventType ,
24
- ( event ) => {
25
- resolve ( event ) ;
26
- } ,
27
- { once : true }
28
- ) ;
29
- } ) ;
42
+ if ( socket . _eventBuffer [ eventType ] . length ) {
43
+ return Promise . resolve ( socket . _eventBuffer [ eventType ] . shift ( ) ) ;
44
+ } else {
45
+ return new Promise ( ( resolve ) => {
46
+ socket . _pendingPromises [ eventType ] . push ( resolve ) ;
47
+ } ) ;
48
+ }
30
49
}
31
50
32
51
async function initLongPollingSession ( ) {
@@ -110,7 +129,7 @@ describe("Engine.IO protocol", () => {
110
129
111
130
describe ( "WebSocket" , ( ) => {
112
131
it ( "successfully opens a session" , async ( ) => {
113
- const socket = new WebSocket (
132
+ const socket = createWebSocket (
114
133
`${ WS_URL } /engine.io/?EIO=4&transport=websocket`
115
134
) ;
116
135
@@ -137,45 +156,45 @@ describe("Engine.IO protocol", () => {
137
156
} ) ;
138
157
139
158
it ( "fails with an invalid 'EIO' query parameter" , async ( ) => {
140
- const socket = new WebSocket (
159
+ const socket = createWebSocket (
141
160
`${ WS_URL } /engine.io/?transport=websocket`
142
161
) ;
143
162
144
163
if ( isNodejs ) {
145
164
socket . on ( "error" , ( ) => { } ) ;
146
165
}
147
166
148
- waitFor ( socket , "close" ) ;
167
+ await waitFor ( socket , "close" ) ;
149
168
150
- const socket2 = new WebSocket (
169
+ const socket2 = createWebSocket (
151
170
`${ WS_URL } /engine.io/?EIO=abc&transport=websocket`
152
171
) ;
153
172
154
173
if ( isNodejs ) {
155
174
socket2 . on ( "error" , ( ) => { } ) ;
156
175
}
157
176
158
- waitFor ( socket2 , "close" ) ;
177
+ await waitFor ( socket2 , "close" ) ;
159
178
} ) ;
160
179
161
180
it ( "fails with an invalid 'transport' query parameter" , async ( ) => {
162
- const socket = new WebSocket ( `${ WS_URL } /engine.io/?EIO=4` ) ;
181
+ const socket = createWebSocket ( `${ WS_URL } /engine.io/?EIO=4` ) ;
163
182
164
183
if ( isNodejs ) {
165
184
socket . on ( "error" , ( ) => { } ) ;
166
185
}
167
186
168
- waitFor ( socket , "close" ) ;
187
+ await waitFor ( socket , "close" ) ;
169
188
170
- const socket2 = new WebSocket (
189
+ const socket2 = createWebSocket (
171
190
`${ WS_URL } /engine.io/?EIO=4&transport=abc`
172
191
) ;
173
192
174
193
if ( isNodejs ) {
175
194
socket2 . on ( "error" , ( ) => { } ) ;
176
195
}
177
196
178
- waitFor ( socket2 , "close" ) ;
197
+ await waitFor ( socket2 , "close" ) ;
179
198
} ) ;
180
199
} ) ;
181
200
} ) ;
@@ -317,7 +336,7 @@ describe("Engine.IO protocol", () => {
317
336
318
337
describe ( "WebSocket" , ( ) => {
319
338
it ( "sends and receives a plain text packet" , async ( ) => {
320
- const socket = new WebSocket (
339
+ const socket = createWebSocket (
321
340
`${ WS_URL } /engine.io/?EIO=4&transport=websocket`
322
341
) ;
323
342
@@ -335,7 +354,7 @@ describe("Engine.IO protocol", () => {
335
354
} ) ;
336
355
337
356
it ( "sends and receives a binary packet" , async ( ) => {
338
- const socket = new WebSocket (
357
+ const socket = createWebSocket (
339
358
`${ WS_URL } /engine.io/?EIO=4&transport=websocket`
340
359
) ;
341
360
socket . binaryType = "arraybuffer" ;
@@ -352,7 +371,7 @@ describe("Engine.IO protocol", () => {
352
371
} ) ;
353
372
354
373
it ( "closes the session upon invalid packet format" , async ( ) => {
355
- const socket = new WebSocket (
374
+ const socket = createWebSocket (
356
375
`${ WS_URL } /engine.io/?EIO=4&transport=websocket`
357
376
) ;
358
377
@@ -412,7 +431,7 @@ describe("Engine.IO protocol", () => {
412
431
413
432
describe ( "WebSocket" , ( ) => {
414
433
it ( "sends ping/pong packets" , async ( ) => {
415
- const socket = new WebSocket (
434
+ const socket = createWebSocket (
416
435
`${ WS_URL } /engine.io/?EIO=4&transport=websocket`
417
436
) ;
418
437
@@ -430,7 +449,7 @@ describe("Engine.IO protocol", () => {
430
449
} ) ;
431
450
432
451
it ( "closes the session upon ping timeout" , async ( ) => {
433
- const socket = new WebSocket (
452
+ const socket = createWebSocket (
434
453
`${ WS_URL } /engine.io/?EIO=4&transport=websocket`
435
454
) ;
436
455
@@ -468,7 +487,7 @@ describe("Engine.IO protocol", () => {
468
487
469
488
describe ( "WebSocket" , ( ) => {
470
489
it ( "forcefully closes the session" , async ( ) => {
471
- const socket = new WebSocket (
490
+ const socket = createWebSocket (
472
491
`${ WS_URL } /engine.io/?EIO=4&transport=websocket`
473
492
) ;
474
493
@@ -485,7 +504,7 @@ describe("Engine.IO protocol", () => {
485
504
it ( "successfully upgrades from HTTP long-polling to WebSocket" , async ( ) => {
486
505
const sid = await initLongPollingSession ( ) ;
487
506
488
- const socket = new WebSocket (
507
+ const socket = createWebSocket (
489
508
`${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
490
509
) ;
491
510
@@ -521,12 +540,13 @@ describe("Engine.IO protocol", () => {
521
540
it ( "ignores HTTP requests with same sid after upgrade" , async ( ) => {
522
541
const sid = await initLongPollingSession ( ) ;
523
542
524
- const socket = new WebSocket (
543
+ const socket = createWebSocket (
525
544
`${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
526
545
) ;
527
546
528
547
await waitFor ( socket , "open" ) ;
529
548
socket . send ( "2probe" ) ;
549
+ await waitFor ( socket , "message" ) ; // "3probe"
530
550
socket . send ( "5" ) ;
531
551
532
552
const pollResponse = await fetch (
@@ -545,15 +565,16 @@ describe("Engine.IO protocol", () => {
545
565
it ( "ignores WebSocket connection with same sid after upgrade" , async ( ) => {
546
566
const sid = await initLongPollingSession ( ) ;
547
567
548
- const socket = new WebSocket (
568
+ const socket = createWebSocket (
549
569
`${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
550
570
) ;
551
571
552
572
await waitFor ( socket , "open" ) ;
553
573
socket . send ( "2probe" ) ;
574
+ await waitFor ( socket , "message" ) ; // "3probe"
554
575
socket . send ( "5" ) ;
555
576
556
- const socket2 = new WebSocket (
577
+ const socket2 = createWebSocket (
557
578
`${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
558
579
) ;
559
580
0 commit comments