diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h index d47f76ceb8..09aa62f7d7 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h @@ -103,6 +103,14 @@ namespace AzNetworking //! @return boolean true on success virtual bool Disconnect(ConnectionId connectionId, DisconnectReason reason) = 0; + //! Sets whether this connection interface can disconnect by virtue of a timeout + //! @param timeoutEnabled If this connection interface will automatically disconnect due to a timeout + virtual void SetTimeoutEnabled(bool timeoutEnabled) = 0; + + //! Whether this connection interface will disconnect by virtue of a time out (does not account for cvars affecting all connections) + //! @return boolean true if this connection will not disconnect on timeout (does not account for cvars affecting all connections) + virtual bool IsTimeoutEnabled() const = 0; + //! Const access to the metrics tracked by this network interface. //! @return const reference to the metrics tracked by this network interface const NetworkInterfaceMetrics& GetMetrics() const; diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp index f9569b5c7e..62335a9b39 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp @@ -174,6 +174,16 @@ namespace AzNetworking return connection->Disconnect(reason, TerminationEndpoint::Local); } + void TcpNetworkInterface::SetTimeoutEnabled(bool timeoutEnabled) + { + m_timeoutEnabled = timeoutEnabled; + } + + bool TcpNetworkInterface::IsTimeoutEnabled() const + { + return m_timeoutEnabled; + } + void TcpNetworkInterface::QueueNewConnection(const PendingConnection& pendingConnection) { m_pendingConnections.PushBackItem(pendingConnection); @@ -306,7 +316,7 @@ namespace AzNetworking { tcpConnection->SendReliablePacket(CorePackets::HeartbeatPacket()); } - else if (net_TcpTimeoutConnections) + else if (net_TcpTimeoutConnections && m_networkInterface.IsTimeoutEnabled()) { tcpConnection->Disconnect(DisconnectReason::Timeout, TerminationEndpoint::Local); return TimeoutResult::Delete; diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h index 1d590da2aa..b9ea88974d 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h @@ -99,6 +99,8 @@ namespace AzNetworking bool WasPacketAcked(ConnectionId connectionId, PacketId packetId) override; bool StopListening() override; bool Disconnect(ConnectionId connectionId, DisconnectReason reason) override; + void SetTimeoutEnabled(bool timeoutEnabled) override; + bool IsTimeoutEnabled() const override; //! @} //! Queues a new incoming connection for this network interface. @@ -154,6 +156,7 @@ namespace AzNetworking AZ::Name m_name; TrustZone m_trustZone; uint16_t m_port = 0; + bool m_timeoutEnabled = true; IConnectionListener& m_connectionListener; TcpConnectionSet m_connectionSet; TcpSocketManager m_tcpSocketManager; diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp index a3ddb856d2..48b3ad57e1 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp @@ -397,6 +397,16 @@ namespace AzNetworking return connection->Disconnect(reason, TerminationEndpoint::Local); } + void UdpNetworkInterface::SetTimeoutEnabled(bool timeoutEnabled) + { + m_timeoutEnabled = timeoutEnabled; + } + + bool UdpNetworkInterface::IsTimeoutEnabled() const + { + return m_timeoutEnabled; + } + bool UdpNetworkInterface::IsEncrypted() const { return m_socket->IsEncrypted(); @@ -729,7 +739,7 @@ namespace AzNetworking { udpConnection->SendUnreliablePacket(CorePackets::HeartbeatPacket()); } - else if (net_UdpTimeoutConnections) + else if (net_UdpTimeoutConnections && m_networkInterface.IsTimeoutEnabled()) { udpConnection->Disconnect(DisconnectReason::Timeout, TerminationEndpoint::Local); return TimeoutResult::Delete; diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h index 7a391c152e..949914da91 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h @@ -104,6 +104,8 @@ namespace AzNetworking bool WasPacketAcked(ConnectionId connectionId, PacketId packetId) override; bool StopListening() override; bool Disconnect(ConnectionId connectionId, DisconnectReason reason) override; + void SetTimeoutEnabled(bool timeoutEnabled) override; + bool IsTimeoutEnabled() const override; //! @} //! Returns true if this is an encrypted socket, false if not. @@ -179,6 +181,7 @@ namespace AzNetworking TrustZone m_trustZone; uint16_t m_port = 0; bool m_allowIncomingConnections = false; + bool m_timeoutEnabled = true; IConnectionListener& m_connectionListener; UdpConnectionSet m_connectionSet; TimeoutQueue m_connectionTimeoutQueue; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp index deb53bacab..fc398182ef 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp @@ -32,6 +32,7 @@ namespace Multiplayer { m_networkEditorInterface = AZ::Interface::Get()->CreateNetworkInterface( AZ::Name(MPEditorInterfaceName), ProtocolType::Tcp, TrustZone::ExternalClientToServer, *this); + m_networkEditorInterface->SetTimeoutEnabled(false); if (editorsv_isDedicated) { uint16_t editorServerPort = DefaultServerEditorPort; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 9030b150e6..d557c65215 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -147,13 +147,9 @@ namespace Multiplayer processLaunchInfo.m_showWindow = true; processLaunchInfo.m_processPriority = AzFramework::ProcessPriority::PROCESSPRIORITY_NORMAL; - // Launch the Server and give it a few seconds to boot up + // Launch the Server AzFramework::ProcessWatcher* outProcess = AzFramework::ProcessWatcher::LaunchProcess( processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); - if (outProcess) - { - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(15000)); - } return outProcess; }