jchristn / WatsonWebsocket

A simple C# async websocket server and client for reliable transmission and receipt of data
MIT License
277 stars 53 forks source link

Occasional InvalidOperationException on server when forcing client disconnect #88

Closed BryanCrotaz closed 2 years ago

BryanCrotaz commented 2 years ago

Occasional failure on multicore machine:

Exception Info: System.InvalidOperationException
   at System.Net.WebSockets.WebSocketBase+<CloseOutputAsyncCore>d__51.MoveNext()

Exception Info: System.AggregateException
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean)
   at System.Threading.Tasks.Task.Wait(Int32, System.Threading.CancellationToken)
   at WatsonWebsocket.WatsonWsServer.DisconnectClient(System.String)
   at Hermes.Core.Server.Websockets.Server.HermesWebSocketChannelServer.KillClient(System.String)
   at Hermes.Core.Server.Websockets.Server.HermesWebSocketSession.CheckPing(System.Object, SilverCurve.Util.IocInterfaces.TimerServiceDelayCompletedArgs)
   at SilverCurve.Util.IocServices.WindowsTimerService.FireRepeatingDelayCompleted(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.TimerQueueTimer.CallCallback()
   at System.Threading.TimerQueueTimer.Fire()
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

Looking into .Net source code, it can happen if WebSocketBase.CloseOutputAsyncCore is called multiple times, overlapping in different threads.