@@ -17,16 +17,35 @@ function sleep(delay) {
1717 return new Promise ( ( resolve ) => setTimeout ( resolve , delay ) ) ;
1818}
1919
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+
2041function 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+ }
3049}
3150
3251async function initLongPollingSession ( ) {
@@ -110,7 +129,7 @@ describe("Engine.IO protocol", () => {
110129
111130 describe ( "WebSocket" , ( ) => {
112131 it ( "successfully opens a session" , async ( ) => {
113- const socket = new WebSocket (
132+ const socket = createWebSocket (
114133 `${ WS_URL } /engine.io/?EIO=4&transport=websocket`
115134 ) ;
116135
@@ -137,45 +156,45 @@ describe("Engine.IO protocol", () => {
137156 } ) ;
138157
139158 it ( "fails with an invalid 'EIO' query parameter" , async ( ) => {
140- const socket = new WebSocket (
159+ const socket = createWebSocket (
141160 `${ WS_URL } /engine.io/?transport=websocket`
142161 ) ;
143162
144163 if ( isNodejs ) {
145164 socket . on ( "error" , ( ) => { } ) ;
146165 }
147166
148- waitFor ( socket , "close" ) ;
167+ await waitFor ( socket , "close" ) ;
149168
150- const socket2 = new WebSocket (
169+ const socket2 = createWebSocket (
151170 `${ WS_URL } /engine.io/?EIO=abc&transport=websocket`
152171 ) ;
153172
154173 if ( isNodejs ) {
155174 socket2 . on ( "error" , ( ) => { } ) ;
156175 }
157176
158- waitFor ( socket2 , "close" ) ;
177+ await waitFor ( socket2 , "close" ) ;
159178 } ) ;
160179
161180 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` ) ;
163182
164183 if ( isNodejs ) {
165184 socket . on ( "error" , ( ) => { } ) ;
166185 }
167186
168- waitFor ( socket , "close" ) ;
187+ await waitFor ( socket , "close" ) ;
169188
170- const socket2 = new WebSocket (
189+ const socket2 = createWebSocket (
171190 `${ WS_URL } /engine.io/?EIO=4&transport=abc`
172191 ) ;
173192
174193 if ( isNodejs ) {
175194 socket2 . on ( "error" , ( ) => { } ) ;
176195 }
177196
178- waitFor ( socket2 , "close" ) ;
197+ await waitFor ( socket2 , "close" ) ;
179198 } ) ;
180199 } ) ;
181200 } ) ;
@@ -317,7 +336,7 @@ describe("Engine.IO protocol", () => {
317336
318337 describe ( "WebSocket" , ( ) => {
319338 it ( "sends and receives a plain text packet" , async ( ) => {
320- const socket = new WebSocket (
339+ const socket = createWebSocket (
321340 `${ WS_URL } /engine.io/?EIO=4&transport=websocket`
322341 ) ;
323342
@@ -335,7 +354,7 @@ describe("Engine.IO protocol", () => {
335354 } ) ;
336355
337356 it ( "sends and receives a binary packet" , async ( ) => {
338- const socket = new WebSocket (
357+ const socket = createWebSocket (
339358 `${ WS_URL } /engine.io/?EIO=4&transport=websocket`
340359 ) ;
341360 socket . binaryType = "arraybuffer" ;
@@ -352,7 +371,7 @@ describe("Engine.IO protocol", () => {
352371 } ) ;
353372
354373 it ( "closes the session upon invalid packet format" , async ( ) => {
355- const socket = new WebSocket (
374+ const socket = createWebSocket (
356375 `${ WS_URL } /engine.io/?EIO=4&transport=websocket`
357376 ) ;
358377
@@ -412,7 +431,7 @@ describe("Engine.IO protocol", () => {
412431
413432 describe ( "WebSocket" , ( ) => {
414433 it ( "sends ping/pong packets" , async ( ) => {
415- const socket = new WebSocket (
434+ const socket = createWebSocket (
416435 `${ WS_URL } /engine.io/?EIO=4&transport=websocket`
417436 ) ;
418437
@@ -430,7 +449,7 @@ describe("Engine.IO protocol", () => {
430449 } ) ;
431450
432451 it ( "closes the session upon ping timeout" , async ( ) => {
433- const socket = new WebSocket (
452+ const socket = createWebSocket (
434453 `${ WS_URL } /engine.io/?EIO=4&transport=websocket`
435454 ) ;
436455
@@ -468,7 +487,7 @@ describe("Engine.IO protocol", () => {
468487
469488 describe ( "WebSocket" , ( ) => {
470489 it ( "forcefully closes the session" , async ( ) => {
471- const socket = new WebSocket (
490+ const socket = createWebSocket (
472491 `${ WS_URL } /engine.io/?EIO=4&transport=websocket`
473492 ) ;
474493
@@ -485,7 +504,7 @@ describe("Engine.IO protocol", () => {
485504 it ( "successfully upgrades from HTTP long-polling to WebSocket" , async ( ) => {
486505 const sid = await initLongPollingSession ( ) ;
487506
488- const socket = new WebSocket (
507+ const socket = createWebSocket (
489508 `${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
490509 ) ;
491510
@@ -521,12 +540,13 @@ describe("Engine.IO protocol", () => {
521540 it ( "ignores HTTP requests with same sid after upgrade" , async ( ) => {
522541 const sid = await initLongPollingSession ( ) ;
523542
524- const socket = new WebSocket (
543+ const socket = createWebSocket (
525544 `${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
526545 ) ;
527546
528547 await waitFor ( socket , "open" ) ;
529548 socket . send ( "2probe" ) ;
549+ await waitFor ( socket , "message" ) ; // "3probe"
530550 socket . send ( "5" ) ;
531551
532552 const pollResponse = await fetch (
@@ -545,15 +565,16 @@ describe("Engine.IO protocol", () => {
545565 it ( "ignores WebSocket connection with same sid after upgrade" , async ( ) => {
546566 const sid = await initLongPollingSession ( ) ;
547567
548- const socket = new WebSocket (
568+ const socket = createWebSocket (
549569 `${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
550570 ) ;
551571
552572 await waitFor ( socket , "open" ) ;
553573 socket . send ( "2probe" ) ;
574+ await waitFor ( socket , "message" ) ; // "3probe"
554575 socket . send ( "5" ) ;
555576
556- const socket2 = new WebSocket (
577+ const socket2 = createWebSocket (
557578 `${ WS_URL } /engine.io/?EIO=4&transport=websocket&sid=${ sid } `
558579 ) ;
559580
0 commit comments