private async Task OnConnection(IPipeConnection connection) { using (connection) { WebSocketConnection socket = null; try { WriteStatus(ConnectionType.Server, "Connected"); WriteStatus(ConnectionType.Server, "Parsing http request..."); var request = await ParseHttpRequest(connection.Input); try { WriteStatus(ConnectionType.Server, "Identifying protocol..."); socket = GetProtocol(connection, ref request); WriteStatus(ConnectionType.Server, $"Protocol: {WebSocketProtocol.Name}"); WriteStatus(ConnectionType.Server, "Authenticating..."); if (!await OnAuthenticateAsync(socket, ref request.Headers)) { throw new InvalidOperationException("Authentication refused"); } WriteStatus(ConnectionType.Server, "Completing handshake..."); await WebSocketProtocol.CompleteServerHandshakeAsync(ref request, socket); } finally { request.Dispose(); // can't use "ref request" or "ref headers" otherwise } WriteStatus(ConnectionType.Server, "Handshake complete hook..."); await OnHandshakeCompleteAsync(socket); connections.TryAdd(socket, socket); WriteStatus(ConnectionType.Server, "Processing incoming frames..."); await socket.ProcessIncomingFramesAsync(this); WriteStatus(ConnectionType.Server, "Exiting..."); await socket.CloseAsync(); } catch (Exception ex) {// meh, bye bye broken connection try { socket?.Dispose(); } catch { } WriteStatus(ConnectionType.Server, ex.StackTrace); WriteStatus(ConnectionType.Server, ex.GetType().Name); WriteStatus(ConnectionType.Server, ex.Message); } finally { WebSocketConnection tmp; if (socket != null) { connections.TryRemove(socket, out tmp); } try { connection.Output.Complete(); } catch { } try { connection.Input.Complete(); } catch { } } } }
private async void SendCloseWhenOutputCompleted() { await _output.Reading; await _webSocket.CloseAsync(); }