private void HandleConnection(IAsyncResult result) { // Start waiting for another client as soon as some client has connected. _listener.BeginAcceptTcpClient(HandleConnection, _listener); try { using (var tcpClient = _listener.EndAcceptTcpClient(result)) using (var stream = tcpClient.GetStream()) { var authorizeMessage = MessageSerializer.Deserialize(stream) as Authorize; var playerId = authorizeMessage.PlayerId; var player = _playerRepository.Find(playerId); if (player == null) { player = new Player(playerId, playerId, 1, null); _playerRepository.Save(player); } var client = new ConnectedClient(playerId, stream); // TODO: Maybe refactor locks to thread-safe collection. // Or maybe leave as it is. More clear, and log is binded to the actual order of things. lock (_lock) { _connectedClients.Add(client); _logger.Log($"{player.Name} has connected."); } try { // Send initial status after connect. Update(playerId); while (true) { var message = MessageSerializer.Deserialize(stream); lock (_lock) { _logger.Log($"Received message: {message}"); _dispatcher.Dispatch(client, message); Update(playerId); } } } catch (Exception exception) { lock (_lock) { _logger.Log($"{player.Name} unexpectedly lost connection. {exception.Message}"); _connectedClients.Remove(client); Update(playerId); } return; } } } catch (Exception exception) { _logger.Log($"A client tried and failed to connect. {exception.Message}"); } }