Пример #1
0
        private Task <bool> StartListenAsync()
        {
            if (_serverOption.IsServiceUdp == true)
            {
                _udpSocket = new UdpSocketEx(_loggerFactory.CreateLogger("ServerUdpSocket"), OnPreProcessUdpRawData);

                var udpEndPoint = NetUtil.GetEndPoint(_serverOption.UdpServerAddress, _serverOption.UdpServerPort);

                if (_udpSocket.CreateServer(udpEndPoint, _serverOption.UdpReuseAddress) == false)
                {
                    _logger.LogError($"Failed to bind udp server : {_udpSocket.LocalPort}");
                    return(Task.FromResult(false));
                }
            }

            _listener = new TcpListener(_serverOption, _loggerFactory.CreateLogger("TcpListener"));
            _listener.NewClientAccepted += OnNewClientAccept;

            if (!_listener.Start())
            {
                _logger.LogError($"Failed to listen {_listener}.");
                return(Task.FromResult(false));
            }

            return(Task.FromResult(true));
        }
Пример #2
0
        public void Close()
        {
            _cts.Cancel();

            NetPacket poolingPacket;

            while (_receivedPacketQueue.TryDequeue(out poolingPacket) == true &&
                   poolingPacket != null)
            {
                NetPool.PacketPool.Free(poolingPacket);
            }

            try
            {
                _udpChannel?.Close();
                _udpChannel?.OnClosed();

                _udpSocket?.Close(false);
                _udpSocket = null;

                _request.Close();
            }
            catch
            {
            }
        }
Пример #3
0
        /// <summary>
        /// 서버와 접속을 해제하고 리소스를 해제한다
        /// </summary>
        public void Close()
        {
            OnSessionClosed();

            try
            {
                _cts.Cancel();
            }
            catch
            {
            }

            NetPacket poolingPacket = null;

            while (_receivedPacketQueue.TryDequeue(out poolingPacket) == true &&
                   poolingPacket != null)
            {
                NetPool.PacketPool.Free(poolingPacket);
            }

            try
            {
                _tcpChannel?.Close();
                _udpChannel?.Close();

                _p2pGroup?.Close();
                _p2pGroup = null;

                if (_connectUdpLoopTask != null)
                {
                    _connectUdpLoopTask = null;
                }

                _udpSocket?.Close(false);
                _udpSocket = null;

                _request.Close();
            }
            catch
            {
            }

            _socket         = null;
            _isUdpConnected = false;
        }
Пример #4
0
        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;
        }
Пример #5
0
        /// <summary>
        /// 서버를 정지
        /// </summary>
        public async Task StopAsync()
        {
            var state = _state;

            if (state != ServerState.Started)
            {
                throw new InvalidOperationException($"The server cannot be stopped right now, because its state is {state}.");
            }

            _state = ServerState.Stopping;

            _logger.LogInformation("Stopping... listener");
            if (_listener.IsRunning)
            {
                await _listener.StopAsync();
            }

            _logger.LogInformation("Stopping... all session");
            await _sessionFactory.ShutdownAsync();

            _updateThread.Join();
            _updateThread = null;

            if (_udpSocket != null)
            {
                _logger.LogInformation("Stopping... udp service");
                _udpSocket.Close(false);
                _udpSocket = null;
            }

            _p2pManager?.Clear();

            _logger.LogInformation("Stopped!");

            _state = ServerState.Stopped;
        }
Пример #6
0
        /// <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);
        }