123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- using System;
- using System.Collections.Generic;
- using System.Net.WebSockets;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using BubbleSocketCore.Simulation;
- using BubbleSocketCore.Websocket;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Logging;
- namespace BubbleSocketCore.Handlers
- {
- class PlayerConnectionHandler : IHandler
- {
- private readonly IConfiguration Configuration;
- private readonly ILoggerFactory LoggerFactory;
- private readonly ILogger Logger;
- public SimulationActionFactory simulationActionFactory { get; private set; }
- public ConnectionManager connectionManager { get; private set; }
- public Simulation.Simulation simulation { get; private set; }
- public PlayerConnectionHandler(IConfiguration configuration, ILoggerFactory loggerFactory)
- {
- Configuration = configuration;
- LoggerFactory = loggerFactory;
- Logger = LoggerFactory.CreateLogger("PlayerConnectionHandler");
- simulationActionFactory = new SimulationActionFactory(Configuration, LoggerFactory);
- connectionManager = ConnectionManager.GetInstance();
- simulation = Simulation.Simulation.GetInstance();
- }
- public void AddSocket(WebSocket webSocket)
- {
- connectionManager.Add(webSocket);
- }
- public bool IsListening(HttpRequest request)
- {
- return request.Path == "/game";
- }
- public async Task Listen(HttpContext context, WebSocket selfSocket, CancellationToken cancellationToken)
- {
- try
- {
- var buffer = WebSocket.CreateClientBuffer(1024 * 4, 1024 * 4);
- WebSocketReceiveResult result = await selfSocket.ReceiveAsync(buffer, cancellationToken);
- while (!result.CloseStatus.HasValue)
- {
- var allBytes = new List<byte>();
- for (int i = 0; i < result.Count; i++)
- {
- allBytes.Add(buffer.Array[i]);
- }
- while (!result.EndOfMessage)
- {
- result = await selfSocket.ReceiveAsync(buffer, cancellationToken);
- for (int i = 0; i < result.Count; i++)
- {
- allBytes.Add(buffer.Array[i]);
- }
- }
- var rawString = Encoding.UTF8.GetString(allBytes.ToArray(), 0, allBytes.Count);
- var rawMessageType = rawString.Substring(0, 2);
- var messageData = rawString.Substring(2, rawString.Length - 2);
- var messageType = SimulationActionType.UNKNOWN;
- ISimulationAction simulationAction = new NoOpSimulationActionType();
- try
- {
- messageType = SimulationActionFactory.ParseActionType(rawMessageType);
- simulationAction = simulationActionFactory.Create(messageType);
- }
- catch (Exception e)
- {
- Logger.LogWarning($"Invalid Message Type: {messageType}: {e.Message}");
- }
- try
- {
- simulationAction.Run(selfSocket, simulationAction.ParseMessageData(messageData));
- }
- catch (System.Text.Json.JsonException e)
- {
- Logger.LogWarning($"Data received was not json: {e.Message}");
- }
- //wait for next input message
- //this is what's failing on server shutdown; the cancellation token isn't right
- result = await selfSocket.ReceiveAsync(buffer, cancellationToken);
- }
- await selfSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, cancellationToken);
- simulationActionFactory.Create(SimulationActionType.Disconnect).Run(selfSocket, "{}");
- }
- catch (WebSocketException e)
- {
- Logger.LogWarning($"Websocket exception: {e.Message}");
- simulationActionFactory.Create(SimulationActionType.Disconnect).Run(selfSocket, "{}");
- }
- catch (OperationCanceledException)
- {
- Logger.LogInformation("Server shutdown request");
- simulationActionFactory.Create(SimulationActionType.Disconnect).Run(selfSocket, "{}");
- }
- catch (Exception e)
- {
- Logger.LogWarning($"Unexpected Exception: {e.ToString()}{e.Message}");
- }
- }
- private async Task Send(WebSocket socket, ArraySegment<byte> data, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
- {
- await socket.SendAsync(data, messageType, endOfMessage, cancellationToken);
- }
- }
- }
|