@@ -24,6 +24,10 @@ public class WebSocket : EasyClient<WebSocketPackage>, IWebSocket
2424 private static readonly Encoding _utf8Encoding = new UTF8Encoding ( false ) ;
2525 private const string _magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" ;
2626
27+ private TaskCompletionSource < WebSocketPackage > _closePackageReceivedTaskSource ;
28+
29+ private bool _packageHandlerMode = false ;
30+
2731 public Uri Uri { get ; private set ; }
2832
2933 public bool AutoPingEnabled { get ; set ; }
@@ -220,7 +224,11 @@ private void WriteHandshakeRequest(PipeWriter writer, string secKey)
220224 writer . Write ( "\r \n " , _asciiEncoding ) ;
221225 }
222226
223- public new void StartReceive ( ) => base . StartReceive ( ) ;
227+ public new void StartReceive ( )
228+ {
229+ base . StartReceive ( ) ;
230+ _packageHandlerMode = true ;
231+ }
224232
225233 public new async ValueTask < WebSocketPackage > ReceiveAsync ( )
226234 => await ReceiveAsync (
@@ -229,6 +237,11 @@ private void WriteHandshakeRequest(PipeWriter writer, string secKey)
229237
230238 internal async ValueTask < WebSocketPackage > ReceiveAsync ( bool handleControlPackage , bool returnControlPackage )
231239 {
240+ if ( _packageHandlerMode )
241+ {
242+ throw new InvalidOperationException ( $ "You cannot call the method { nameof ( ReceiveAsync ) } if you already setup the client to process packages by PackageHandler.") ;
243+ }
244+
232245 var package = await base . ReceiveAsync ( ) ;
233246
234247 if ( package == null )
@@ -254,6 +267,15 @@ protected override async ValueTask OnPackageReceived(WebSocketPackage package)
254267 {
255268 if ( package . OpCode != OpCode . Binary && package . OpCode != OpCode . Text )
256269 {
270+ if ( package . OpCode == OpCode . Close && _closePackageReceivedTaskSource is TaskCompletionSource < WebSocketPackage > closePackageReceivedTaskSource )
271+ {
272+ if ( Interlocked . CompareExchange ( ref _closePackageReceivedTaskSource , null , closePackageReceivedTaskSource ) == closePackageReceivedTaskSource )
273+ {
274+ closePackageReceivedTaskSource . SetResult ( package ) ;
275+ return ;
276+ }
277+ }
278+
257279 await HandleControlPackage ( package ) ;
258280 return ;
259281 }
@@ -349,14 +371,21 @@ public async ValueTask CloseAsync(CloseReason closeReason, string message = null
349371 Reason = closeReason ,
350372 ReasonText = message
351373 } ;
374+
375+ var closePackageReceivedTaskSource = default ( TaskCompletionSource < WebSocketPackage > ) ;
376+
377+ if ( _packageHandlerMode )
378+ {
379+ closePackageReceivedTaskSource = _closePackageReceivedTaskSource = new ( ) ;
380+ }
352381
353382 await SendAsync ( _packageEncoder , package ) ;
354383
355384 State = WebSocketState . CloseSent ;
356385
357- var closeHandshakeResponse = await ReceiveAsync (
358- handleControlPackage : false ,
359- returnControlPackage : true ) ;
386+ var closeHandshakeResponse = closePackageReceivedTaskSource != null
387+ ? await closePackageReceivedTaskSource . Task
388+ : await ReceiveAsync ( handleControlPackage : false , returnControlPackage : true ) ;
360389
361390 if ( closeHandshakeResponse . OpCode != OpCode . Close )
362391 {
0 commit comments