/// <summary> /// Accepts the WebSocket connection. /// This is a blocking call so it must be called within an independent thread. /// </summary> /// <param name="context">The context.</param> /// <param name="ct">The cancellation token.</param> /// <returns> /// A task that represents the asynchronous of websocket connection operation. /// </returns> public async Task AcceptWebSocket(IHttpContext context, CancellationToken ct) { // first, accept the websocket $"{ServerName} - Accepting WebSocket . . .".Debug(nameof(WebSocketsServer)); var subProtocol = ResolveSubProtocol(context); var webSocketContext = await context.AcceptWebSocketAsync(ReceiveBufferSize, subProtocol).ConfigureAwait(false); // remove the disconnected clients CollectDisconnected(); lock (_syncRoot) { // add the newly-connected client _mWebSockets.Add(webSocketContext); } $"{ServerName} - WebSocket Accepted - There are {WebSockets.Count} sockets connected.".Debug( nameof(WebSocketsServer)); OnClientConnected(webSocketContext, context.Request.LocalEndPoint, context.Request.RemoteEndPoint); try { if (webSocketContext.WebSocket is WebSocket systemWebSocket) { await ProcessSystemWebsocket(webSocketContext, systemWebSocket.SystemWebSocket, ct) .ConfigureAwait(false); } else { await ProcessEmbedIOWebSocket(webSocketContext, ct).ConfigureAwait(false); } } catch (TaskCanceledException) { // ignore } catch (Exception ex) { ex.Log(nameof(WebSocketsServer)); } finally { // once the loop is completed or connection aborted, remove the WebSocket RemoveWebSocket(webSocketContext); } }