Example #1
0
        /// <summary>
        /// Removes client from local repository.
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        private TcpClientInfo RemoveClientFromRepository(string clientId)
        {
            TcpClientInfo client = null;

            _clientRepo.TryRemove(clientId, out client);
            return(client);
        }
Example #2
0
        /// <summary>
        /// Gets client from local repository
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        private TcpClientInfo GetClientFromRepository(string clientId)
        {
            TcpClientInfo client = null;

            _clientRepo.TryGetValue(clientId, out client);
            return(client);
        }
Example #3
0
        /// <summary>
        /// Disconnects a client
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public bool DisconnectClient(string clientId)
        {
            TcpClientInfo client = RemoveClientFromRepository(clientId);

            client?.Dispose();
            return(client != null);
        }
Example #4
0
        /// <summary>
        /// Reads data from stream
        /// </summary>
        /// <param name="client"></param>
        /// <param name="clientInfo"></param>
        /// <param name="ct"></param>
        protected async Task ReadData(TcpClientInfo client)
        {
            // get buffer size
            int bufferSize = _config.SocketBufferSize;

            // Buffer for reading data
            byte[] buffer = new byte[bufferSize];

            // Get a stream object for reading and writing
            NetworkStream stream = client.Client.GetStream();

            // Loop to receive all the data sent by the client.
            stream.ReadTimeout = 2000;
            int i = 0;

            while (true)
            {
                // read data from steram
                try
                {
                    i = await stream.ReadAsync(buffer, 0, bufferSize);
                }
                catch (IOException)
                {
                    break;
                }
                catch (ObjectDisposedException)
                {
                    break;
                } catch (Exception)
                {
                    break;
                }

                // No data (end of strem)
                if (i == 0)
                {
                    break;
                }

                // received data
                var receivedMessages = client.DataProcessor.ProcessReceivedRawData(buffer, i);

                // message received
                if (receivedMessages != null && receivedMessages.Any())
                {
                    receivedMessages.ToList().ForEach((msg) => _ = DataReceived(msg, client.Info.Id));
                }
            }

            // Close connection
            client.Dispose();
        }
Example #5
0
        /// <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);
        }
Example #6
0
        /// <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);
        }
Example #7
0
        /// <summary>
        /// Sends data to client
        /// </summary>
        /// <param name="clientId"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task <bool> SendMessageToClient(string clientId, byte[] data)
        {
            TcpClientInfo client = GetClientFromRepository(clientId);

            if (client != null)
            {
                DataContainer message = new DataContainer
                {
                    ClientId = clientId,
                    Payload  = data,
                    Time     = DateTime.Now
                };
                return(await SendMessage(client, message));
            }

            return(false);
        }
Example #8
0
        /// <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);
        }
Example #9
0
        /// <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);
        }
Example #10
0
 /// <summary>
 /// Puts client to local repository.
 /// </summary>
 /// <param name="client"></param>
 private void PutClientToRepository(TcpClientInfo client)
 {
     _clientRepo.TryAdd(client.Info.Id, client);
 }
Example #11
0
        /// <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);
        }