/// <summary> /// Starts a TCP server and listens for incoming <see cref="TcpConnection"/>s. /// </summary> public async Task StartTCPListener() { if (IsTCPOnline) { return; } tcpListener = new TcpListener(System.Net.IPAddress.Parse(IPAddress), Port); IsTCPOnline = !IsTCPOnline; tcpListener.Start(); try { while (IsTCPOnline) { TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync(); TcpConnection tcpConnection = CreateTcpConnection(tcpClient); tcpConnection.NetworkConnectionClosed += connectionClosed; tcpConnection.ConnectionEstablished += udpConnectionReceived; connections.GetOrAdd(tcpConnection, new List <UdpConnection>()); //Inform all subscribers. if (connectionEstablished != null && connectionEstablished.GetInvocationList().Length > 0) { connectionEstablished(tcpConnection, ConnectionType.TCP); } KnownTypes.ForEach(tcpConnection.AddExternalPackets); } } //The TCP-Listener has been shut down. catch (ObjectDisposedException) { } }
/// <summary> /// Starts to listen to the given port and ipAddress. /// </summary> public async void StartTCPListener() { if (IsTCPOnline) { return; } tcpListener = new TcpListener(System.Net.IPAddress.Parse(IPAddress), Port); IsTCPOnline = !IsTCPOnline; tcpListener.Start(); while (IsTCPOnline) { TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync(); TcpConnection tcpConnection = ConnectionFactory.CreateTcpConnection(tcpClient); tcpConnection.ConnectionClosed += connectionClosed; tcpConnection.ConnectionEstablished += udpConnectionReceived; connections.GetOrAdd(tcpConnection, new List <UdpConnection>()); //Inform all subscribers. if (connectionEstablished != null && connectionEstablished.GetInvocationList().Length > 0) { connectionEstablished(tcpConnection, ConnectionType.TCP); } KnownTypes.ForEach(tcpConnection.AddExternalPackets); //Now that the server registered all the methods, unlock the client. tcpConnection.UnlockRemoteConnection(); } }
/// <summary> /// Handles when a <see cref="UdpConnection"/> successfully connects to the server. /// </summary> /// <param name="tcpConnection">The parent <see cref="TcpConnection"/>.</param> /// <param name="udpConnection">The connected <see cref="UdpConnection"/>.</param> private void udpConnectionReceived(TcpConnection tcpConnection, UdpConnection udpConnection) { if (!AllowUDPConnections || this[tcpConnection].Count >= UDPConnectionLimit) { CloseReason closeReason = (this[tcpConnection].Count >= UDPConnectionLimit) ? CloseReason.UdpLimitExceeded : CloseReason.InvalidUdpRequest; tcpConnection.Close(closeReason, true); return; } this[tcpConnection].Add(udpConnection); udpConnection.NetworkConnectionClosed += connectionClosed; KnownTypes.ForEach(udpConnection.AddExternalPackets); //Inform all subscribers. if (connectionEstablished != null && connectionEstablished.GetInvocationList().Length > 0) { connectionEstablished(udpConnection, ConnectionType.UDP); } }
/// <summary> /// Opens the new UDP connection and applies the already registered packet handlers. /// </summary> private async Task OpenNewUDPConnection() { Tuple <UdpConnection, ConnectionResult> result = await CreateUdpConnection(); if (result.Item2 != ConnectionResult.Connected) { Reconnect(); return; } udpConnection = result.Item1; //Restore old state by adding old packets udpConnection.RestorePacketHandler(udpPacketHandlerBackup); //Restore new state by adding packets the user wanted to register while the connection was dead. udpPacketHandlerBuffer.ForEach(t => { MethodInfo registerPacketHandler = typeof(Connection).GetMethod("RegisterPacketHandler", BindingFlags.NonPublic | BindingFlags.Instance); registerPacketHandler = registerPacketHandler.MakeGenericMethod(t.Item1); registerPacketHandler.Invoke(udpConnection, new object[2] { t.Item2, t.Item3 }); }); udpStaticPacketHandlerBuffer.ForEach(t => { MethodInfo registerPacketHandler = typeof(Connection).GetMethod("RegisterStaticPacketHandler", BindingFlags.NonPublic | BindingFlags.Instance); registerPacketHandler = registerPacketHandler.MakeGenericMethod(t.Item1); registerPacketHandler.Invoke(udpConnection, new object[] { t.Item2 }); }); udpConnection.ConnectionClosed += (c, cc) => { udpPacketHandlerBackup = cc.ObjectMapper; connectionLost?.Invoke(udpConnection, ConnectionType.UDP, c); Reconnect(); }; sendFastBuffer.ForEach(udpConnection.Send); sendFastObjectBuffer.ForEach(p => udpConnection.Send(p.Item1, p.Item2)); //Restore new state by removing the packets the user wanted to unregister while the connection was dead. udpUnPacketHandlerBuffer.ForEach(t => { MethodInfo unRegisterPacketHandler = typeof(Connection).GetMethod("UnRegisterPacketHandler"); unRegisterPacketHandler = unRegisterPacketHandler.MakeGenericMethod(t.Item1); unRegisterPacketHandler.Invoke(udpConnection, new object[] { t.Item2 }); }); udpStaticUnPacketHandlerBuffer.ForEach(t => { MethodInfo unRegisterPacketHandler = typeof(Connection).GetMethod("UnRegisterStaticPacketHandler"); unRegisterPacketHandler = unRegisterPacketHandler.MakeGenericMethod(t); unRegisterPacketHandler.Invoke(udpConnection, null); }); KnownTypes.ForEach(UdpConnection.AddExternalPackets); //Clear the buffers since we added and removed the packet types. sendFastBuffer.Clear(); sendFastObjectBuffer.Clear(); udpPacketHandlerBuffer.Clear(); udpUnPacketHandlerBuffer.Clear(); udpStaticPacketHandlerBuffer.Clear(); udpStaticUnPacketHandlerBuffer.Clear(); if (!UdpConnection.IsAlive) { return; //Connection could already be dead because of the prePackets. } connectionEstablished?.Invoke(udpConnection, ConnectionType.UDP); }