/// <summary> /// Adds client to connectedClients then asynchronously sends the dynamic data to them and disconnects the socket. /// </summary> /// <returns>Task that finishes when the message has been sent.</returns> async Task ProcessReadyClient(ReadyClient c, byte[] dynamicData) { var cc = new ConnectedClient { playerID = c.playerID, timeoutTicks = 0, relUpdateSocket = c.relUpdatesSocket, lastPolledCUpdate = 0, }; Debug.Assert(c.dynDataSocket.RemoteEndPoint is IPEndPoint, "Socket should use IP for communication,"); //Use address from previous connection. //TEMP Shift ports by playerID=Allows multiple clients on one computer cc.updateAddress = new IPEndPoint((c.dynDataSocket.RemoteEndPoint as IPEndPoint).Address, Ports.serverUpdates + c.playerID); connectedClients.Add(cc.playerID, cc); Console.WriteLine($"Client {cc.playerID} is now connected."); await Communication.TCPSendMessageAsync(c.dynDataSocket, dynamicData); c.dynDataSocket.Shutdown(SocketShutdown.Send); int read = c.dynDataSocket.Receive(new byte[5]); //Wait until clients shutdowns its socket = dynamic data received. Debug.Assert(read == 0); Console.WriteLine($"Dynamic data for {cc.playerID} has been sent,closing connection."); c.dynDataSocket.Close(); }
/// <summary> /// Handles newly connected client. /// </summary> /// <param name="client">Incoming socket</param> /// <param name="ID">ID of the client</param> /// <returns>Task that completes when the client has been handled.</returns> async Task HandleClientConnectionAssync(Socket client, int ID, ConnectingStaticData con) { Console.WriteLine($"Connectd to {ID}({client.RemoteEndPoint})"); await Communication.TCPSendMessageAsync(client, ConnectingStaticData.Encode(con)); bool clientReady = await Communication.TCPReceiveACKAsync(client); Console.WriteLine($"Recieved ACK from {ID}"); Debug.Assert(clientReady); ReadyClient c = new ReadyClient { playerID = con.PlayerID, dynDataSocket = client, relUpdatesSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp), }; //Establish a channel for reliable updates. //TEMP Shift ports by playerID=Allows multiple clients on one computer var relAddress = new IPEndPoint((c.dynDataSocket.RemoteEndPoint as IPEndPoint).Address, Ports.relServerUpdates + con.PlayerID); c.relUpdatesSocket.Connect(relAddress); Console.WriteLine($"Created a reliable channel for server commands fro {ID}."); var tmp = readyClients; while (tmp != Interlocked.CompareExchange(ref readyClients, tmp.Add(c), tmp)) { tmp = readyClients; } Console.WriteLine($"{ID} is ready"); }