public void RegisterModule(AsyncWebSocketServerModule module) { _modules.Add(module.GetType().FullName, module); }
internal async Task Start() { int origin = Interlocked.CompareExchange(ref _state, _connecting, _none); if (origin == _disposed) { throw new ObjectDisposedException("This websocket session has been disposed when connecting."); } else if (origin != _none) { throw new InvalidOperationException("This websocket session is in invalid state when connecting."); } try { ResetKeepAlive(); ConfigureClient(); var negotiator = NegotiateStream(_tcpClient.GetStream()); if (!negotiator.Wait(ConnectTimeout)) { await Close(WebSocketCloseCode.TlsHandshakeFailed, "SSL/TLS handshake timeout."); throw new TimeoutException(string.Format( "Negotiate SSL/TSL with remote [{0}] timeout [{1}].", this.RemoteEndPoint, ConnectTimeout)); } _stream = negotiator.Result; _receiveBuffer = _bufferManager.BorrowBuffer(); _receiveBufferOffset = 0; var handshaker = OpenHandshake(); if (!handshaker.Wait(ConnectTimeout)) { throw new TimeoutException(string.Format( "Handshake with remote [{0}] timeout [{1}].", this.RemoteEndPoint, ConnectTimeout)); } if (!handshaker.Result) { var responseBuffer = WebSocketServerHandshaker.CreateOpenningHandshakeBadRequestResponse(this); await _stream.WriteAsync(responseBuffer, 0, responseBuffer.Length); throw new WebSocketException(string.Format( "Handshake with remote [{0}] failed.", this.RemoteEndPoint)); } if (Interlocked.CompareExchange(ref _state, _connected, _connecting) != _connecting) { await InternalClose(false); // connected with wrong state throw new ObjectDisposedException("This websocket session has been disposed after connected."); } _log.DebugFormat("Session started for [{0}] on [{1}] in module [{2}] with session count [{3}].", this.RemoteEndPoint, this.StartTime.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"), _module.GetType().Name, this.Server.SessionCount); bool isErrorOccurredInUserSide = false; try { await _module.OnSessionStarted(this); } catch (Exception ex) { isErrorOccurredInUserSide = true; await HandleUserSideError(ex); } if (!isErrorOccurredInUserSide) { _keepAliveTracker.StartTimer(); await Process(); } else { await InternalClose(true); // user side handle tcp connection error occurred } } catch (Exception ex) when(ex is TimeoutException || ex is WebSocketException) { _log.Error(string.Format("Session [{0}] exception occurred, [{1}].", this, ex.Message), ex); await InternalClose(true); // handle tcp connection error occurred throw; } }