예제 #1
0
        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}");
            }
        }