private async Task <PlayerConnection> LoginPlayer(WebSocket socket) { byte[] buffer = new byte[1024 * 4]; var input = await socket.ReadInputAsync(buffer); var loginInput = input as TokenInput; if (loginInput == null) { throw new Exception($"Это не {nameof(TokenInput)}"); } var playerId = loginInput.PlayerId; var token = loginInput.Token; if (playerId == null || await _storage.CheckHumanPlayerAsync(playerId.Value, token) == false) { playerId = Guid.NewGuid(); token = Guid.NewGuid().ToString("N"); await _storage.CreateHumanPlayerAsync(playerId.Value, token); } PlayerConnection playerConnection = _outConnectionManager.PlayerConnected(playerId.Value, new OutputChanel(socket, _loggerFactory)); await socket.SendDataAsync(new SetTokenCommand { playerId = playerId.Value.ToString("N"), token = token }); return(playerConnection); }
public async Task Invoke(HttpContext context) { if (!context.WebSockets.IsWebSocketRequest) { return; } var socket = await context.WebSockets.AcceptWebSocketAsync(); PlayerConnection playerConnection = null; try { playerConnection = await LoginPlayer(socket); await Receive(socket, playerConnection); } finally { if (playerConnection != null) { _outConnectionManager.ConnectionClosed(playerConnection.ConnectionId); } } //TODO - investigate the Kestrel exception thrown when this is the last middleware //await _next.Invoke(context); }
private async Task Receive(WebSocket socket, PlayerConnection playerConnection) { byte[] buffer = new byte[1024 * 4]; _world.Pipe.Post(new PlayerConnected(playerConnection.PlayerId, playerConnection.OutputChanel.Pipe, PlayerType.Human)); while (socket.State == WebSocketState.Open) { var input = await socket.ReadInputAsync(buffer); if (input == null) { return; } _world.Pipe.Post(new PlayerInput(playerConnection.PlayerId, input)); } }
internal PlayerConnection PlayerConnected(Guid playerId, OutputChanel outputChanel) { lock (Locker) { foreach (var connection in PlayerConnections.Where(x => x.PlayerId == playerId).ToArray()) { RemoveConnection(connection); } var newConnection = new PlayerConnection(playerId, outputChanel); PlayerConnections.Add(newConnection); DisploseAndRemoveTimer(playerId); return(newConnection); } }
private void RemoveConnection(PlayerConnection connection) { connection.OutputChanel.Pipe.Complete(); PlayerConnections.Remove(connection); }