public async ValueTask StartAsync(Socket sck, SessionParameter <TSession> ssnPrmtr) { socket = sck ?? throw new ArgumentNullException(nameof(sck)); parameter = ssnPrmtr ?? throw new ArgumentNullException(nameof(ssnPrmtr)); if (behavior == null) { parameter.logger.MemberNotSetWarn("Session Behavior", "SetSessionBehavior"); } int prevState = Interlocked.CompareExchange(ref _state, (int)SessionState.Starting, (int)SessionState.None); if (prevState != (int)SessionState.None) { throw new InvalidOperationException($"The session has an invalid initial state. : Session state is {(SessionState)prevState}"); } behavior?.OnStartBefore(this); await ProcessStart(); _state = (int)SessionState.Running; await ProcessStartAfter(); behavior?.OnStartAfter(this); }
protected async ValueTask OnAcceptFromListener(IListener listener, Socket sck) { TSession session = null; string sessionId = string.Empty; try { // 서버 상태 체크. if (state != ServerState.Running) { throw new Exception("A socket connection was attempted with the server shut down."); } if (sessionCount >= socketServerConfig.maxConnection) { return; } // 소켓 상태 설정 // TODO : 해당 로직 적절한 공간으로 이동. SocketSetting(sck); // 세션이 시작 전 새로운 세션 아이디를 받아둔다(해당 아이디는 예약된다.) if (!sessionContainer.TryPreoccupancySessionId(out sessionId)) { throw new Exception("Unable to create Session Id."); } // MsgFilter 가져오기 var msgFilter = msgFilterFactory.Get(); if (msgFilter == null) { throw new Exception("MsgFilterFactory.Get retunred null"); } // session 생성 session = CreateSession(); if (session == null) { throw new Exception("CreateSession retunred null"); } // 사용자 측 세션 설정 호출 sessionConfigrator?.Invoke(session); // 세션 생성 시 필요한 데이터 설정. var ssnPrmtr = new SessionParameter <TSession>(sessionId, msgFilter, OnStopFromSession, _sessionLogger); // 설정 완료 후 생성한 ID로 컨테이너 등록. sessionContainer.SetSession(sessionId, session); // NOTE : 정상적인 플로우를 위해 세션 시작과 관련된 모든 작업은 마치고 session을 시작해야한다. await session.StartAsync(sck, ssnPrmtr) .ConfigureAwait(false); } catch (Exception ex) { OnError(ex); } finally { // 세션이 시작되지 못했다면 소켓을 중단. if (session == null || session.state != SessionState.Running) { sck.SafeClose(); // 세션 등록 취소 if (!string.IsNullOrEmpty(sessionId)) { sessionContainer.RemoveSession(sessionId); } } } }