/// <summary> /// 세션을 P2P그룹에서 제거함 /// </summary> /// <param name="session">제거할 세션</param> /// <returns>성공여부</returns> public bool Leave(ServerSession session) { var member = Find(session.SessionId); if (member == null) { return(false); } lock (_memberList) { try { if (session.SessionId == _masterSessionId) { if (_memberList.Count > 1) { ChangeMaster(false, false); } } foreach (var m in _memberList) { m.SendLeaveP2pGroup( Id, member.Session.SessionId, _masterSessionId); } } finally { _memberList.Remove(member); member = null; } if (_memberList.Count == 0) { _masterSessionId = ushort.MaxValue; } } //Console.WriteLine("Leave P2P Group : {0} {1} {2}", m_groupSessionKey, session.GetSessionKey(), m_masterSessionKey); return(true); }
internal void OnSessionClose(ISession session) { #warning 추후 최적화를 하자 ServerSession s = session as ServerSession; lock (_p2pGroupMap) { foreach (var kvp in _p2pGroupMap) { try { kvp.Value.Leave(s); } catch { } } } }
public DefaultSessionFactory( ServerOption serverOption, ILoggerFactory loggerFactory, NetStatistic statistic, Func <SessionCreateInfo, ServerSession> createSessionFunc = null) { createSessionFunc = createSessionFunc ?? CreateSession; _sessionQueue = new ConcurrentQueue <ISession>(); _maxSession = serverOption.MaxSession; var createInfo = new SessionCreateInfo(); for (int i = 0; i < _maxSession; ++i) { TcpChannel tcpChannel = new TcpChannel( serverOption, loggerFactory.CreateLogger(nameof(TcpChannel)), statistic); UdpChannel udpChannel = null; if (serverOption.IsServiceUdp) { udpChannel = new UdpChannel( serverOption, loggerFactory.CreateLogger(nameof(UdpChannel)), statistic, 0); } createInfo.SessionId = (ushort)(i + 1); createInfo.TcpChannel = tcpChannel; createInfo.UdpChannel = udpChannel; createInfo.Statistic = statistic; ServerSession session = createSessionFunc(createInfo); _sessionQueue.Enqueue(session); } }
private async Task HandleSession(ServerSession session) { _sessionManager.InsertSession(session); try { _logger.LogInformation($"A new session connected: {session.SessionId}"); session.OnSessionConnected(); OnSessionConnected?.Invoke(session); try { await session.RunAsync(); } catch (Exception e) { _logger.LogError(e, $"Failed to handle the session {session.SessionId}."); session.Close(); } if (_udpSocket != null) { _udpSocket.RemoveSession(session); } _logger.LogInformation($"The session disconnected: {session.SessionId}"); OnSessionClosed?.Invoke(session); await session.OnSessionClosed(); } catch (Exception e) { _logger.LogError(e, $"Failed to handle the session {session.SessionId}."); } finally { _sessionManager.RemoveSession(session); _sessionFactory.Release(session); } }
/// <summary> /// 세션을 P2P에 가입시킴 /// </summary> /// <param name="session">가입시킬 세션</param> /// <returns>성공여부</returns> public bool Join(ServerSession session) { if (Contains(session.SessionId) == true) { return(false); } var p2pMember = new P2pMember(); try { lock (_memberList) { if (_memberList.Count == 0) { _masterSessionId = session.SessionId; } p2pMember.SetSession(session); _memberList.AddLast(p2pMember); p2pMember.SendJoinP2pGroup( Id, session.SessionId, MasterSessionId, session.UdpChannel.RemoteEndPoint, session.UdpChannel.LocalEndPoint); foreach (var member in _memberList) { if (member.Session == session) { continue; } // 나한테 다른 유저 정보를 보내자 p2pMember.SendJoinP2pGroup( Id, member.SessionId, _masterSessionId, member.Session.UdpChannel.RemoteEndPoint, member.Session.UdpChannel.LocalEndPoint); // 다른사람한테 내정보를 보내자 member.SendJoinP2pGroup( Id, session.SessionId, _masterSessionId, session.UdpChannel.RemoteEndPoint, session.UdpChannel.LocalEndPoint); } } } catch { return(false); } //Console.WriteLine("Join P2P Group : {0} {1} {2}", m_groupSessionKey, session.GetSessionKey(), m_masterSessionKey); return(true); }