@@ -34,7 +34,7 @@ public abstract class WebsocketBaseController<T> : OpenShockControllerBase, IAsy
3434 private CancellationTokenSource ? _linkedSource ;
3535
3636 protected CancellationToken LinkedToken ;
37-
37+
3838 /// <summary>
3939 /// Channel for multithreading thread safety of the websocket, MessageLoop is the only reader for this channel
4040 /// </summary>
@@ -53,7 +53,6 @@ protected WebsocketBaseController(ILogger<WebsocketBaseController<T>> logger)
5353 Logger = logger ;
5454 }
5555
56-
5756 /// <inheritdoc />
5857 [ NonAction ]
5958 public ValueTask QueueMessage ( T data )
@@ -210,14 +209,18 @@ protected virtual Task SendWebSocketMessage(T message, WebSocket websocket, Canc
210209
211210 #endregion
212211
212+ private CancellationTokenSource _receiveCancellationTokenSource = new ( ) ;
213+
213214 /// <summary>
214215 /// Main receiver logic for the websocket
215216 /// </summary>
216217 /// <returns></returns>
217218 [ NonAction ]
218219 private async Task Logic ( )
219220 {
220- while ( ! LinkedToken . IsCancellationRequested )
221+ using var linkedReceiverToken = CancellationTokenSource . CreateLinkedTokenSource ( LinkedToken , _receiveCancellationTokenSource . Token ) ;
222+
223+ while ( ! linkedReceiverToken . IsCancellationRequested )
221224 {
222225 try
223226 {
@@ -241,7 +244,7 @@ private async Task Logic()
241244 return ;
242245 }
243246
244- if ( ! await HandleReceive ( ) )
247+ if ( ! await HandleReceive ( linkedReceiverToken . Token ) )
245248 {
246249 // HandleReceive returned false, we will close the connection after this
247250 Logger . LogDebug ( "HandleReceive returned false, closing connection" ) ;
@@ -273,7 +276,18 @@ private async Task Logic()
273276 /// </summary>
274277 /// <returns>True if you want to continue the receiver loop, false if you want to terminate</returns>
275278 [ NonAction ]
276- protected abstract Task < bool > HandleReceive ( ) ;
279+ protected abstract Task < bool > HandleReceive ( CancellationToken cancellationToken ) ;
280+
281+ [ NonAction ]
282+ protected async Task ForceClose ( WebSocketCloseStatus closeStatus , string ? statusDescription )
283+ {
284+ await _receiveCancellationTokenSource . CancelAsync ( ) ;
285+
286+ if ( WebSocket is { State : WebSocketState . CloseReceived or WebSocketState . Open } )
287+ {
288+ await WebSocket . CloseOutputAsync ( closeStatus , statusDescription , LinkedToken ) ;
289+ }
290+ }
277291
278292 /// <summary>
279293 /// Send initial data to the client
0 commit comments