public P2pSession(NetClient netClient, ushort sessionId, IPEndPoint remoteEp, IPEndPoint localEp) { _netClient = netClient; _sessionId = sessionId; _cts = new CancellationTokenSource(); _udpSocket = new UdpSocketEx( netClient.LoggerFactory.CreateLogger("P2pSessionUdpSocket"), netClient.OnPreProcessUdpRawData, netClient.UdpSocketReceiveRawAsyncObject); _udpSocket.CreateClient(); _tcpChannel = null; _udpChannel = new UdpChannel( _netClient.ClientOption, _netClient.LoggerFactory.CreateLogger(nameof(UdpChannel)), _netClient.Statistic, sessionId); _udpChannel.Init(_cts); _udpChannel.PacketReceived = OnReceiveFromChannel; _udpChannel.SetSocket(netClient.UdpSocket); _udpChannel.RemoteEndPoint = remoteEp; _udpChannel.LocalEndPoint = localEp; _udpChannel.TempEndPoint = remoteEp; _udpChannel.RelayEndPoint = NetUtil.GetEndPoint(netClient.ClientOption.UdpServerAddress, netClient.ClientOption.UdpServerPort); _udpChannel.IsRunMtu = false; _udpChannel.IsRunPing = false; _receivedPacketQueue = new ConcurrentQueue <NetPacket>(); _packetReader = new NetDataReader(); _request = new SessionRequest(this, netClient.Statistic); _state = SessionState.Connected; }
/// <summary> /// 서버로 연결을 시도합니다 /// </summary> /// <param name="timeout">타임아웃</param> /// <returns>성공여부</returns> public async Task <bool> ConnectAsync(TimeSpan?timeout = null) { if (_socket != null || State != SessionState.Closed) { return(false); } try { State = SessionState.Initialized; TimeSpan currentTimeout = timeout ?? TimeSpan.FromSeconds(10); _cts = new CancellationTokenSource(); _serverEndPoint = NetUtil.GetEndPoint(_clientOption.TcpServerAddress, _clientOption.TcpServerPort); _serverUdpEndPoint = NetUtil.GetEndPoint(_clientOption.UdpServerAddress, _clientOption.UdpServerPort); if (_clientOption.IsServiceUdp) { _udpSocket = new UdpSocketEx( _loggerFactory.CreateLogger("ClientUdpSocket"), OnPreProcessUdpRawData, UdpSocketReceiveRawAsyncObject); _udpSocket.CreateClient(); } _isUdpConnected = false; _socket = new Socket(SocketType.Stream, ProtocolType.Tcp); await _socket.ConnectAsync(_serverEndPoint).TimeoutAfter(currentTimeout); if (_socket.Connected == false) { _logger.LogInformation("Fail to connect"); State = SessionState.Closed; _socket.Close(); _socket = null; return(false); } if (_tcpChannel != null) { _tcpChannel.Init(_cts); _tcpChannel.PacketReceived = OnReceiveFromChannel; _tcpChannel.SetSocket(_socket); } if (_udpChannel != null) { _udpChannel.Init(_cts); _udpChannel.PacketReceived = OnReceiveFromChannel; if (_udpSocket != null) { _udpChannel.SetSocket(_udpSocket); _udpChannel.LocalEndPoint = _udpSocket.GetLocalEndPoint(); } } RunAsync().DoNotAwait(); if (_clientOption.IsServiceUdp) { currentTimeout = TimeSpan.FromSeconds(10); while (IsUdpConnected == false && State == SessionState.Initialized) { await Task.Delay(100); currentTimeout -= TimeSpan.FromMilliseconds(100); if (currentTimeout < TimeSpan.FromMilliseconds(0)) { throw new Exception("udp connection timeout"); } } } OnSessionConnected(); _logger.LogInformation("Connect succeed"); return(true); } catch (Exception ex) { OnError(ex); Close(); } State = SessionState.Closed; return(false); }