コード例 #1
0
ファイル: TcpSocketBase.cs プロジェクト: jrozac/Layer4Stack
        /// <summary>
        /// Message received handler
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="clientId"></param>
        private async Task DataReceived(byte[] msg, string clientId)
        {
            //  create message model
            DataContainer model = new DataContainer {
                ClientId = clientId, Payload = msg, Time = DateTime.Now
            };

            // trigger event
            _ = TaskUtil.RunAction(() => MsgReceivedAction?.Invoke(model), _logger);
            await Task.FromResult(true);
        }
コード例 #2
0
ファイル: TcpServerSocket.cs プロジェクト: jrozac/Layer4Stack
        /// <summary>
        /// Tcp server start task
        /// </summary>
        /// <param name="cts"></param>
        /// <returns></returns>
        public async Task <bool> ServerStart()
        {
            // already started
            if (_server != null)
            {
                _logger.LogInformation("Server already started.");
                return(false);
            }

            // clar clients repository
            _clientRepo.Clear();

            // Init TCP listener
            var server = _config.IpAddress == null?TcpListener.Create(_config.Port) : new TcpListener(IPAddress.Parse(_config.IpAddress), _config.Port);

            // start server
            bool status = false;

            try
            {
                // Start listening for client requests.
                server.Start();

                // set started
                status = true;
            }
            catch (Exception e)
            {
                _logger.LogError("Server failed to start on port {port}. Exception: {exception}", _config.Port, e.Message);
            }

            // set server
            Interlocked.Exchange(ref _server, server);

            // raise status event
            if (status)
            {
                _ = TaskUtil.RunAction(() => ServerStartedAction?.Invoke(_config), _logger);
            }
            else
            {
                _ = TaskUtil.RunAction(() => ServerStartFailureAction?.Invoke(_config), _logger);
            }

            // wait for clients (keep it run in background)
            if (status)
            {
                _ = WaitForClientsLoop();
            }

            // finished
            return(await Task.FromResult(status));
        }
コード例 #3
0
ファイル: TcpSocketBase.cs プロジェクト: jrozac/Layer4Stack
        /// <summary>
        /// Send message
        /// </summary>
        /// <param name="client"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        protected async Task <bool> SendMessage(TcpClientInfo client, DataContainer message)
        {
            // decorate message to be sent over network
            byte[] msg = client.DataProcessor.FilterSendData(message.Payload);

            // sent message
            bool status = await SendData(client.Client, msg);

            // raise sent
            if (status)
            {
                _ = TaskUtil.RunAction(() => MsgSentAction?.Invoke(message), _logger);
            }
            return(status);
        }
コード例 #4
0
ファイル: TcpClientSocket.cs プロジェクト: jrozac/Layer4Stack
        /// <summary>
        /// Connect to server
        /// </summary>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task <bool> Connect()
        {
            // create client or return
            if (_client != null)
            {
                return(true);
            }

            // init model info
            var client = new TcpClientInfo
            {
                Info = new ClientInfo()
                {
                    Time      = DateTime.Now,
                    Port      = _config.Port,
                    IpAddress = _config.IpAddress,
                    Id        = Guid.NewGuid().ToString()
                },
                Client        = new TcpClient(),
                DataProcessor = _createDataProcessorFunc()
            };

            // connect
            try
            {
                await client.Client.ConnectAsync(_config.IpAddress, _config.Port);
            }
            catch (Exception e)
            {
                _logger.LogError("Connection failed with error: {message}.", e.Message);

                // client connected failed
                _ = TaskUtil.RunAction(() => ClientConnectionFailureAction?.Invoke(client.Info), _logger);

                // return false
                return(false);
            }

            // set client
            Interlocked.Exchange(ref _client, client);

            // handle client
            _ = HandleClient();

            // return success
            return(true);
        }
コード例 #5
0
ファイル: TcpServerSocket.cs プロジェクト: jrozac/Layer4Stack
        /// <summary>
        /// Handles a connected client
        /// </summary>
        /// <param name="client"></param>
        /// <param name="clientInfo"></param>
        private async Task HandleClient(TcpClientInfo client)
        {
            // trigger connected event
            _ = TaskUtil.RunAction(() => ClientConnectedAction?.Invoke(client.Info), _logger);

            // add client to repository
            PutClientToRepository(client);

            // continuously reads data (stops here until cancelled
            await ReadData(client);

            // remove client from repository
            RemoveClientFromRepository(client.Info.Id);

            // raise clinet disconnected
            _ = TaskUtil.RunAction(() => ClientDisconnectedAction?.Invoke(client.Info), _logger);
        }
コード例 #6
0
ファイル: TcpClientSocket.cs プロジェクト: jrozac/Layer4Stack
        /// <summary>
        /// Handles a connected client
        /// </summary>
        /// <param name="client"></param>
        /// <param name="ct"></param>
        private async Task HandleClient()
        {
            // client connected
            _ = TaskUtil.RunAction(() => ClientConnectedAction?.Invoke(_client.Info), _logger);

            // continuously reads data
            await ReadData(_client);

            // remove client from repository
            var client = Interlocked.Exchange(ref _client, null);

            _client?.Client.GetStream().Close();
            _client?.Client?.Close();
            _client = null;

            // trigger diconnected event
            _ = TaskUtil.RunAction(() => ClientDisconnectedAction?.Invoke(client?.Info), _logger);
        }
コード例 #7
0
ファイル: TcpServerSocket.cs プロジェクト: jrozac/Layer4Stack
        /// <summary>
        /// Wait for clients loop
        /// </summary>
        /// <returns></returns>
        private async Task WaitForClientsLoop()
        {
            try
            {
                // Enter the listening loop.
                while (true)
                {
                    // Wait for client to connect.
                    TcpClient client = await _server.AcceptTcpClientAsync();

                    // set client info
                    TcpClientInfo clientModel = new TcpClientInfo
                    {
                        Info = new ClientInfo
                        {
                            Time      = DateTime.Now,
                            Port      = _config.Port,
                            IpAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString(),
                            Id        = Guid.NewGuid().ToString()
                        },
                        Client        = client,
                        DataProcessor = _createDataProcessorFunc(),
                    };

                    // Handle client in background
                    _ = HandleClient(clientModel);
                }
            }
            // socket errro
            catch (SocketException)
            {
                _logger.LogWarning("Server stopped. SocketException exception occured.");
            }
            // Listener was stopped.
            catch (ObjectDisposedException)
            {
                _logger.LogWarning("Server stopped. ObjectDisposedException exception occured.");
            } catch (InvalidOperationException)
            {
                _logger.LogWarning("Invalid operation exception.");
            }
            finally
            {
                // stop server
                try
                {
                    TcpListener tcpListener = null;
                    var         srv         = Interlocked.Exchange(ref _server, tcpListener);
                    srv?.Stop();
                } catch (SocketException)
                {
                }

                // disconnect client
                var clients = _clientRepo.Values.ToList();
                _clientRepo.Clear();
                clients.ForEach(c => {
                    try
                    {
                        c.Dispose();
                    } catch (Exception)
                    {
                    }
                });

                // log stop
                _logger.LogInformation("Server stopped.");
            }

            // server stopped
            _ = TaskUtil.RunAction(() => ServerStoppedAction?.Invoke(_config), _logger);
        }