public void ReceiveTcp(AsyncSocket.ReadResult rr) { Read(rr.Buffer); }
public void RemoveTarget(AsyncSocket socket) { bool b; _connectedClients.TryRemove(socket, out b); PlayerEndPoint endPoint; // perhaps add socket to PlayerEndPoint so we can always efficiently remove the player from _connectedClients if (_playerEndPoints.TryRemove(socket.IpEndPoint, out endPoint)) { Console.WriteLine($"Client: {socket.IpEndPoint.ToString().Replace("::ffff:", "")} disconnected."); bool b2; _udpEndPoints.TryRemove(endPoint.IpEndPoint, out b2); Game game; if (BoDService.PlayerIngame.TryRemove(endPoint.PlayerId, out game)) { game.RemovePlayer(endPoint.PlayerId); Console.WriteLine($"Player: {endPoint.PlayerId} quit game: {game.Id}."); } } socket.Dispose(); }
private async Task AcceptClientAsync(Socket socket) { await Task.Yield(); AsyncSocket s = null; try { s = new AsyncSocket(socket); } catch (SocketException) { socket.Dispose(); return; } _connectedClients.TryAdd(s, true); Console.WriteLine($"Client connected: {s.IpEndPoint?.ToString().Replace("::ffff:", "")}"); try { while (true) { Task<AsyncSocket.ReadResult> receive = s.ReceiveAsync(); await receive; ReceiveTcp(receive.Result); } } catch (SocketException) { } catch (ObjectDisposedException) { } finally { RemoveTarget(s); } }
public void RemoveTarget(AsyncSocket socket) { LightEvent e; _connectedClients.TryRemove(socket, out e); PlayerEndPoint endPoint; // perhaps add socket to PlayerEndPoint so we can always efficiently remove the player from _connectedClients if (_playerEndPoints.TryRemove(socket.IpEndPoint, out endPoint)) { BoDConsole.WriteLine($"Client: {socket.IpEndPoint.Address.MapToIPv4()}:{socket.IpEndPoint.Port} disconnected."); // If any PlayerEndPoint, other than the one that was just removed, // references PlayerId, the player must be connected on another PlayerEndPoint. if (_playerEndPoints.Values.All(p => p.PlayerId != endPoint.PlayerId)) { Game game; if (BoDService.PlayerIngame.TryRemove(endPoint.PlayerId, out game)) { game.RemovePlayer(endPoint.PlayerId); } } } socket.Dispose(); }
private async Task ReceiveFromClientAsync(AsyncSocket s) { while (true) { AsyncSocket.ReadResult result = await s.ReceiveAsync(); LightEvent e; if (_connectedClients.TryGetValue(s, out e)) { // Reset the LightEvent's timer to prevent timeout. e.Reset(); } Read(result.Buffer, s.IpEndPoint); } }
/// <summary> /// Awaits a message from the client containing a sessionId. /// If the sessionId matches any we have given out. Assign the found PlayerEndPoint /// to the client. We write back the sessionId again as a signal that the client should /// begin attempting to "connect" with UDP. /// </summary> /// <param name="socket"> The TCP socket for the client. </param> /// <returns> true if the client succesfully verified through TCP. false otherwise. </returns> private async Task<bool> AddTCPTarget(AsyncSocket socket) { AsyncSocket.ReadResult result = await socket.ReceiveAsync(); if (result.BytesRead != SESSIONID_LENGTH) { return false; } string sessionId = Convert.ToBase64String(result.Buffer); PlayerEndPoint playerEndPoint; if (!_playerSessionTokens.TryGetValue(sessionId, out playerEndPoint)) { return false; } if (sessionId != playerEndPoint.SessionId) return false; playerEndPoint.TCPSocket = socket; await socket.SendMessage(result.Buffer); return _playerEndPoints.TryAdd(socket.IpEndPoint, playerEndPoint); }
private async Task AcceptClientAsync(Socket socket) { await Task.Yield(); AsyncSocket s = null; try { s = new AsyncSocket(socket); } catch (SocketException) { socket.Dispose(); return; } // Cancel the attempt to communicate with the client on both TCP and UDP after 10 sec. CancellationTokenSource cts = new CancellationTokenSource(TCP_TIMEOUT); Task timeout = new Task(async () => { await Task.Delay(TCP_TIMEOUT); throw new SocketException(); }); try { Task<bool> tcp = AddTCPTarget(s); // Only await timeout once. If tcp finishes first we wont get an exception when timeout finishes. await Task.WhenAny(tcp, timeout); // await tcp here aswell because we want the result of it. Once we got the result of AddTCPTarget(), // we await the result of AddUDPTarget. PlayerEndPoint playerEndPoint; if (await tcp && _playerEndPoints.TryGetValue(s.IpEndPoint, out playerEndPoint) && await AddUDPTarget(playerEndPoint, cts.Token)) { // Timeout the TCP and UDP connection to a client if we dont receive a TCP message // at least once per 10 sec. _connectedClients.TryAdd(s, new LightEvent(TCP_TIMEOUT, () => { RemoveTarget(s); })); playerEndPoint.InactivityEvent = new LightEvent(60000, () => { RemoveTarget(s); }); BoDConsole.WriteLine($"Client connected: {s.IpEndPoint.Address.MapToIPv4()}"); // Start reading actual game related messages from the client. await ReceiveFromClientAsync(s); } } catch (SocketException) { } catch (ObjectDisposedException) { } finally { cts.Dispose(); RemoveTarget(s); } }
private async Task AcceptClientAsync(Socket socket) { await Task.Yield(); AsyncSocket s = null; try { s = new AsyncSocket(socket); _connectedClients.TryAdd(s, true); Console.WriteLine($"Client connected: {s.IpEndPoint?.ToString().Replace("::ffff:", "")}"); while (true) { Task<AsyncSocket.ReadResult> receive = s.ReceiveAsync(); await receive; ReceiveTcp(receive.Result); } } catch (SocketException) { } finally { if (s != null) { bool b; if (_connectedClients.TryRemove(s, out b)) { IPEndPoint ip = s.IpEndPoint; if (ip != null) { Console.WriteLine($"Client: {ip.ToString().Replace("::ffff:", "")} disconnected."); RemoveTarget(ip); } } s.Dispose(); } socket?.Close(); } }