@@ -108,7 +108,7 @@ public bool PerformClientUpgrade(HttpResponse response, Guid id)
108108 accept = true ;
109109 }
110110 }
111-
111+
112112 // Failed to perform WebSocket handshake
113113 if ( ! accept || ! connection || ! upgrade )
114114 {
@@ -303,20 +303,10 @@ public void PrepareSendFrame(byte opcode, bool mask, byte[] buffer, long offset,
303303 /// <param name="size">Buffer size</param>
304304 public void PrepareReceiveFrame ( byte [ ] buffer , long offset , long size )
305305 {
306- var index = 0 ;
307-
308- // Clear received data after WebSocket frame was processed
309- if ( WsReceived )
306+ lock ( WsReceiveLock )
310307 {
311- WsReceived = false ;
312- WsHeaderSize = 0 ;
313- WsPayloadSize = 0 ;
314- WsReceiveBuffer . Clear ( ) ;
315- Array . Clear ( WsReceiveMask , 0 , WsReceiveMask . Length ) ;
316- }
308+ var index = 0 ;
317309
318- while ( size > 0 )
319- {
320310 // Clear received data after WebSocket frame was processed
321311 if ( WsReceived )
322312 {
@@ -327,32 +317,20 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
327317 Array . Clear ( WsReceiveMask , 0 , WsReceiveMask . Length ) ;
328318 }
329319
330- // Prepare WebSocket frame opcode and mask flag
331- if ( WsReceiveBuffer . Count < 2 )
320+ while ( size > 0 )
332321 {
333- for ( int i = 0 ; i < 2 ; ++ i , ++ index , -- size )
322+ // Clear received data after WebSocket frame was processed
323+ if ( WsReceived )
334324 {
335- if ( size == 0 )
336- return ;
337- WsReceiveBuffer . Add ( buffer [ offset + index ] ) ;
325+ WsReceived = false ;
326+ WsHeaderSize = 0 ;
327+ WsPayloadSize = 0 ;
328+ WsReceiveBuffer . Clear ( ) ;
329+ Array . Clear ( WsReceiveMask , 0 , WsReceiveMask . Length ) ;
338330 }
339- }
340331
341- byte opcode = ( byte ) ( WsReceiveBuffer [ 0 ] & 0x0F ) ;
342- bool fin = ( ( WsReceiveBuffer [ 0 ] >> 7 ) & 0x01 ) != 0 ;
343- bool mask = ( ( WsReceiveBuffer [ 1 ] >> 7 ) & 0x01 ) != 0 ;
344- int payload = WsReceiveBuffer [ 1 ] & ( ~ 0x80 ) ;
345-
346- // Prepare WebSocket frame size
347- if ( payload <= 125 )
348- {
349- WsHeaderSize = 2 + ( mask ? 4 : 0 ) ;
350- WsPayloadSize = payload ;
351- WsReceiveBuffer . Capacity = WsHeaderSize + WsPayloadSize ;
352- }
353- else if ( payload == 126 )
354- {
355- if ( WsReceiveBuffer . Count < 4 )
332+ // Prepare WebSocket frame opcode and mask flag
333+ if ( WsReceiveBuffer . Count < 2 )
356334 {
357335 for ( int i = 0 ; i < 2 ; ++ i , ++ index , -- size )
358336 {
@@ -362,83 +340,108 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
362340 }
363341 }
364342
365- payload = ( ( WsReceiveBuffer [ 2 ] << 8 ) | ( WsReceiveBuffer [ 3 ] << 0 ) ) ;
366- WsHeaderSize = 4 + ( mask ? 4 : 0 ) ;
367- WsPayloadSize = payload ;
343+ byte opcode = ( byte ) ( WsReceiveBuffer [ 0 ] & 0x0F ) ;
344+ bool fin = ( ( WsReceiveBuffer [ 0 ] >> 7 ) & 0x01 ) != 0 ;
345+ bool mask = ( ( WsReceiveBuffer [ 1 ] >> 7 ) & 0x01 ) != 0 ;
346+ int payload = WsReceiveBuffer [ 1 ] & ( ~ 0x80 ) ;
347+
348+ // Prepare WebSocket frame size
349+ if ( payload <= 125 )
350+ {
351+ WsHeaderSize = 2 + ( mask ? 4 : 0 ) ;
352+ WsPayloadSize = payload ;
368353 WsReceiveBuffer . Capacity = WsHeaderSize + WsPayloadSize ;
369- }
370- else if ( payload == 127 )
371- {
372- if ( WsReceiveBuffer . Count < 10 )
354+ }
355+ else if ( payload == 126 )
373356 {
374- for ( int i = 0 ; i < 8 ; ++ i , ++ index , -- size )
357+ if ( WsReceiveBuffer . Count < 4 )
375358 {
376- if ( size == 0 )
377- return ;
378- WsReceiveBuffer . Add ( buffer [ offset + index ] ) ;
359+ for ( int i = 0 ; i < 2 ; ++ i , ++ index , -- size )
360+ {
361+ if ( size == 0 )
362+ return ;
363+ WsReceiveBuffer . Add ( buffer [ offset + index ] ) ;
364+ }
379365 }
366+
367+ payload = ( ( WsReceiveBuffer [ 2 ] << 8 ) | ( WsReceiveBuffer [ 3 ] << 0 ) ) ;
368+ WsHeaderSize = 4 + ( mask ? 4 : 0 ) ;
369+ WsPayloadSize = payload ;
370+ WsReceiveBuffer . Capacity = WsHeaderSize + WsPayloadSize ;
380371 }
372+ else if ( payload == 127 )
373+ {
374+ if ( WsReceiveBuffer . Count < 10 )
375+ {
376+ for ( int i = 0 ; i < 8 ; ++ i , ++ index , -- size )
377+ {
378+ if ( size == 0 )
379+ return ;
380+ WsReceiveBuffer . Add ( buffer [ offset + index ] ) ;
381+ }
382+ }
381383
382- payload = ( ( WsReceiveBuffer [ 2 ] << 56 ) | ( WsReceiveBuffer [ 3 ] << 48 ) | ( WsReceiveBuffer [ 4 ] << 40 ) | ( WsReceiveBuffer [ 5 ] << 32 ) | ( WsReceiveBuffer [ 6 ] << 24 ) | ( WsReceiveBuffer [ 7 ] << 16 ) | ( WsReceiveBuffer [ 8 ] << 8 ) | ( WsReceiveBuffer [ 9 ] << 0 ) ) ;
383- WsHeaderSize = 10 + ( mask ? 4 : 0 ) ;
384- WsPayloadSize = payload ;
384+ payload = ( ( WsReceiveBuffer [ 2 ] << 56 ) | ( WsReceiveBuffer [ 3 ] << 48 ) | ( WsReceiveBuffer [ 4 ] << 40 ) | ( WsReceiveBuffer [ 5 ] << 32 ) | ( WsReceiveBuffer [ 6 ] << 24 ) | ( WsReceiveBuffer [ 7 ] << 16 ) | ( WsReceiveBuffer [ 8 ] << 8 ) | ( WsReceiveBuffer [ 9 ] << 0 ) ) ;
385+ WsHeaderSize = 10 + ( mask ? 4 : 0 ) ;
386+ WsPayloadSize = payload ;
385387 WsReceiveBuffer . Capacity = WsHeaderSize + WsPayloadSize ;
386- }
388+ }
387389
388- // Prepare WebSocket frame mask
389- if ( mask )
390- {
391- if ( WsReceiveBuffer . Count < WsHeaderSize )
390+ // Prepare WebSocket frame mask
391+ if ( mask )
392392 {
393- for ( int i = 0 ; i < 4 ; ++ i , ++ index , -- size )
393+ if ( WsReceiveBuffer . Count < WsHeaderSize )
394394 {
395- if ( size == 0 )
396- return ;
397- WsReceiveBuffer . Add ( buffer [ offset + index ] ) ;
398- WsReceiveMask [ i ] = buffer [ offset + index ] ;
395+ for ( int i = 0 ; i < 4 ; ++ i , ++ index , -- size )
396+ {
397+ if ( size == 0 )
398+ return ;
399+ WsReceiveBuffer . Add ( buffer [ offset + index ] ) ;
400+ WsReceiveMask [ i ] = buffer [ offset + index ] ;
401+ }
399402 }
400403 }
401- }
402404
403- int total = WsHeaderSize + WsPayloadSize ;
404- int length = Math . Min ( total - WsReceiveBuffer . Count , ( int ) size ) ;
405+ int total = WsHeaderSize + WsPayloadSize ;
406+ int length = Math . Min ( total - WsReceiveBuffer . Count , ( int ) size ) ;
405407
406- // Prepare WebSocket frame payload
407- WsReceiveBuffer . AddRange ( buffer [ ( ( int ) offset + index ) ..( ( int ) offset + index + length ) ] ) ;
408- index += length ;
409- size -= length ;
408+ // Prepare WebSocket frame payload
409+ WsReceiveBuffer . AddRange ( buffer [ ( ( int ) offset + index ) ..( ( int ) offset + index + length ) ] ) ;
410+ index += length ;
411+ size -= length ;
410412
411- // Process WebSocket frame
412- if ( WsReceiveBuffer . Count == total )
413- {
414- int bufferOffset = WsHeaderSize ;
413+ // Process WebSocket frame
414+ if ( WsReceiveBuffer . Count == total )
415+ {
416+ int bufferOffset = WsHeaderSize ;
415417
416- // Unmask WebSocket frame content
417- if ( mask )
418- for ( int i = 0 ; i < WsPayloadSize ; ++ i )
419- WsReceiveBuffer [ bufferOffset + i ] ^= WsReceiveMask [ i % 4 ] ;
418+ // Unmask WebSocket frame content
419+ if ( mask )
420+ for ( int i = 0 ; i < WsPayloadSize ; ++ i )
421+ WsReceiveBuffer [ bufferOffset + i ] ^= WsReceiveMask [ i % 4 ] ;
420422
421- WsReceived = true ;
423+ WsReceived = true ;
422424
423- if ( ( opcode & WS_PING ) == WS_PING )
424- {
425- // Call the WebSocket ping handler
426- _wsHandler . OnWsPing ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
427- }
428- else if ( ( opcode & WS_PONG ) == WS_PONG )
429- {
430- // Call the WebSocket pong handler
431- _wsHandler . OnWsPong ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
432- }
433- else if ( ( opcode & WS_CLOSE ) == WS_CLOSE )
434- {
435- // Call the WebSocket close handler
436- _wsHandler . OnWsClose ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
437- }
438- else if ( ( ( opcode & WS_TEXT ) == WS_TEXT ) || ( ( opcode & WS_BINARY ) == WS_BINARY ) )
439- {
440- // Call the WebSocket received handler
441- _wsHandler . OnWsReceived ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
425+ if ( ( opcode & WS_PING ) == WS_PING )
426+ {
427+ // Call the WebSocket ping handler
428+ _wsHandler . OnWsPing ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
429+ }
430+ else if ( ( opcode & WS_PONG ) == WS_PONG )
431+ {
432+ // Call the WebSocket pong handler
433+ _wsHandler . OnWsPong ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
434+ }
435+ else if ( ( opcode & WS_CLOSE ) == WS_CLOSE )
436+ {
437+ // Call the WebSocket close handler
438+ _wsHandler . OnWsClose ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
439+ }
440+ else if ( ( ( opcode & WS_TEXT ) == WS_TEXT ) || ( ( opcode & WS_BINARY ) == WS_BINARY ) )
441+ {
442+ // Call the WebSocket received handler
443+ _wsHandler . OnWsReceived ( WsReceiveBuffer . ToArray ( ) , bufferOffset , WsPayloadSize ) ;
444+ }
442445 }
443446 }
444447 }
@@ -449,42 +452,48 @@ public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
449452 /// </summary>
450453 public int RequiredReceiveFrameSize ( )
451454 {
452- if ( WsReceived )
453- return 0 ;
455+ lock ( WsReceiveLock )
456+ {
457+ if ( WsReceived )
458+ return 0 ;
454459
455- // Required WebSocket frame opcode and mask flag
456- if ( WsReceiveBuffer . Count < 2 )
457- return 2 - WsReceiveBuffer . Count ;
460+ // Required WebSocket frame opcode and mask flag
461+ if ( WsReceiveBuffer . Count < 2 )
462+ return 2 - WsReceiveBuffer . Count ;
458463
459- bool mask = ( ( WsReceiveBuffer [ 1 ] >> 7 ) & 0x01 ) != 0 ;
460- int payload = WsReceiveBuffer [ 1 ] & ( ~ 0x80 ) ;
464+ bool mask = ( ( WsReceiveBuffer [ 1 ] >> 7 ) & 0x01 ) != 0 ;
465+ int payload = WsReceiveBuffer [ 1 ] & ( ~ 0x80 ) ;
461466
462- // Required WebSocket frame size
463- if ( ( payload == 126 ) && ( WsReceiveBuffer . Count < 4 ) )
464- return 4 - WsReceiveBuffer . Count ;
465- if ( ( payload == 127 ) && ( WsReceiveBuffer . Count < 10 ) )
466- return 10 - WsReceiveBuffer . Count ;
467+ // Required WebSocket frame size
468+ if ( ( payload == 126 ) && ( WsReceiveBuffer . Count < 4 ) )
469+ return 4 - WsReceiveBuffer . Count ;
470+ if ( ( payload == 127 ) && ( WsReceiveBuffer . Count < 10 ) )
471+ return 10 - WsReceiveBuffer . Count ;
467472
468- // Required WebSocket frame mask
469- if ( ( mask ) & & ( WsReceiveBuffer . Count < WsHeaderSize ) )
470- return WsHeaderSize - WsReceiveBuffer . Count ;
473+ // Required WebSocket frame mask
474+ if ( ( mask ) & & ( WsReceiveBuffer . Count < WsHeaderSize ) )
475+ return WsHeaderSize - WsReceiveBuffer . Count ;
471476
472- // Required WebSocket frame payload
473- return WsHeaderSize + WsPayloadSize - WsReceiveBuffer . Count ;
477+ // Required WebSocket frame payload
478+ return WsHeaderSize + WsPayloadSize - WsReceiveBuffer . Count ;
479+ }
474480 }
475481
476482 /// <summary>
477483 /// Clear WebSocket send/receive buffers
478484 /// </summary>
479485 public void ClearWsBuffers ( )
480486 {
481- WsReceived = false ;
482- WsHeaderSize = 0 ;
483- WsPayloadSize = 0 ;
484- WsReceiveBuffer . Clear ( ) ;
485- Array . Clear ( WsReceiveMask , 0 , WsReceiveMask . Length ) ;
487+ lock ( WsReceiveLock )
488+ {
489+ WsReceived = false ;
490+ WsHeaderSize = 0 ;
491+ WsPayloadSize = 0 ;
492+ WsReceiveBuffer . Clear ( ) ;
493+ Array . Clear ( WsReceiveMask , 0 , WsReceiveMask . Length ) ;
494+ }
486495
487- lock ( WsSendLock )
496+ lock ( WsSendLock )
488497 {
489498 WsSendBuffer . Clear ( ) ;
490499 Array . Clear ( WsSendMask , 0 , WsSendMask . Length ) ;
@@ -508,6 +517,10 @@ public void ClearWsBuffers()
508517 /// </summary>
509518 internal int WsPayloadSize ;
510519
520+ /// <summary>
521+ /// Receive buffer lock
522+ /// </summary>
523+ internal readonly object WsReceiveLock = new object ( ) ;
511524 /// <summary>
512525 /// Receive buffer
513526 /// </summary>
@@ -531,5 +544,3 @@ public void ClearWsBuffers()
531544 internal readonly byte [ ] WsSendMask = new byte [ 4 ] ;
532545 }
533546}
534-
535-
0 commit comments