unosquare / embedio

A tiny, cross-platform, module based web server for .NET
http://unosquare.github.io/embedio
Other
1.46k stars 176 forks source link

WebSocketModule.OnClientDisconnectedAsync called twice when closing and reopening websocket #528

Closed azixMcAze closed 2 years ago

azixMcAze commented 3 years ago

Context

Hello, I am doing some tests with websockets. I close an existing websocket and I open a new one just after:

if(ws)
   ws.close();
ws = new WebSocket(`ws://${host}/ws`, []);

I have an minimal WebsocketModule:

    class TestWebSocketModule : WebSocketModule
    {
        public TestWebSocketModule(string urlPath) : base(urlPath, false) { }

        protected override Task OnMessageReceivedAsync(IWebSocketContext context, byte[] buffer, IWebSocketReceiveResult result)
        {
            string messageStr = Encoding.GetString(buffer);
            Debug.Log($"[{context.Id}] OnMessageReceivedAsync\n{messageStr}");
            return Task.CompletedTask;
        }

        protected override Task OnClientConnectedAsync(IWebSocketContext context)
        {
            Debug.Log($"[{context.Id}] OnClientConnectedAsync");
            return Task.CompletedTask;
        }

        protected override Task OnClientDisconnectedAsync(IWebSocketContext context)
        {
            Debug.Log($"[{context.Id}] OnClientDisconnectedAsync");
            return Task.CompletedTask;
        }
    }

Observed Behaviour

The second time I re-open socket, OnClientDisconnectedAsync is called twice for the existing websocket that I juste closed.

I get these log messages:

[189a7lnBhUe+ZWx0n6Dmtw] OnClientConnectedAsync (initial open) [ce14wIQRbkyfBgmzkNkQTA] OnClientConnectedAsync (1st repoen) [189a7lnBhUe+ZWx0n6Dmtw] OnClientDisconnectedAsync [ce14wIQRbkyfBgmzkNkQTA] OnClientDisconnectedAsync (2nd reopen) [STMccCfqYkq/83YctmrMbA] OnClientConnectedAsync [ce14wIQRbkyfBgmzkNkQTA] OnClientDisconnectedAsync

After tracing the code, It seems that OnClientDisconnectedAsync is called the first time from PurgeDisconnectedContexts() in OnRequestAsync() and the second time from the finallyblock in OnRequestAsync().

Enabling the watchdog or not does not change the behaviour

Expected Behavior

I expect that OnClientDisconnectedAsync is only called once per context

Versions

I observed the problem with EmbedIO v3.4.3 from nuget and build from source. I tested with Firefox 89 and Chrome 91 on mac. EmbedIO is called from the Unity Editor.

rdeago commented 3 years ago

Hello @azixMcAze, so nice to have you back here, despite the unhappy circumstances.

Thanks for the detailed report. Unfortunately I won't be able to investigate this issue in the next couple weeks. Maybe @geoperez might want to chime in; otherwise I'm starting to work on it on the second week of August. I have pinned the issue so it doesn't get marked as stale in the meantime.