Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Ping of Client much higher when initialised from Script then from NetworkManager

Discussion in 'Relay' started by Sycab, Oct 24, 2022.

Thread Status:
Not open for further replies.
  1. Sycab

    Sycab

    Joined:
    Jul 11, 2020
    Posts:
    10
    Hey folks,

    I am currently creating a game using the UGS Relay and Lobby Services.
    When I start my Host/Client from the GUI Buttons of the NetworkManager in the Inspector my Client (running on the same machine) has a ping of 5-10ms. However if I start my Client/Host through script with the Lobby system etc. the client suddenly has a ping of 80-120ms.

    My ping measured through speed tests in the browser is ~20ms. The settings of the NetworkManager are all at default. For testing I have disabled all Server/ClientRpc's including the NetworkAnimator Component.
    The ping in Unity I is measured through the RuntimeNetworkStats provided by the MultiplayerTools and through:

    NetworkManager.NetworkConfig.NetworkTransport.GetCurrentRtt(clientId)

    Is there anything wrong with my code, or is this ping to be expected since it is always routed through the Relay Server?

    I am using Unity 2021.3.11f1 with Netcode for GameObjects 1.0.2, Relay 1.0.4, Lobby 1.0.3 and Multiplayer Tools 1.0.0.
    Thanks in advance for any help, and let me know if you need more information or clarification on the issue.

    To create and join the lobby I have followed TaroDev's tutorial on the topic.
    Code used to create/join lobby and initialise services:
    (Full code can be seen in tutorial and the linked GitHub repo)

    Code (CSharp):
    1.  public static class Authentication{
    2.         public static string PlayerId { get; private set; }
    3.  
    4.         public static async Task Login() {
    5.             if (UnityServices.State == ServicesInitializationState.Uninitialized) {
    6.                 var options = new InitializationOptions();
    7.  
    8.  
    9. #if UNITY_EDITOR
    10.                 // It's used to differentiate the clients, otherwise lobby will count them as the same
    11.                 if (ClonesManager.IsClone()) {
    12.                     options.SetProfile(ClonesManager.GetArgument());
    13.                 }
    14.                 else {
    15.                     options.SetProfile("Primary");
    16.                 }
    17. #endif
    18.            
    19.                 await UnityServices.InitializeAsync(options);
    20.             }
    21.  
    22.             if (!AuthenticationService.Instance.IsSignedIn) {
    23.                 await AuthenticationService.Instance.SignInAnonymouslyAsync();
    24.                 PlayerId = AuthenticationService.Instance.PlayerId;
    25.             }
    26.         }
    27.     }
    Code (CSharp):
    1.  public static async Task CreateLobbyWithAllocation(RelayHostData data)
    2.     {
    3.         // Create a relay allocation and generate a join code to share with the lobby
    4.         var a = await RelayService.Instance.CreateAllocationAsync(MAX_PLAYERS);
    5.         var joinCode = await RelayService.Instance.GetJoinCodeAsync(a.AllocationId);
    6.  
    7.         RelayHostData relayHostData = new RelayHostData
    8.         {
    9.             Key = a.Key,
    10.             JoinCode = joinCode,
    11.             MaxPlayers = MAX_PLAYERS,
    12.             Port = (ushort) a.RelayServer.Port,
    13.             AllocationID = a.AllocationId,
    14.             AllocationIDBytes = a.AllocationIdBytes,
    15.             IPv4Address = a.RelayServer.IpV4,
    16.             ConnectionData = a.ConnectionData
    17.         };
    18.  
    19.         var lobbyOptions = new CreateLobbyOptions
    20.         {
    21.             IsPrivate = !data.IsPublic,
    22.             Data = new Dictionary<string, DataObject>
    23.             {
    24.                 {Constants.RelayJoinKey, new DataObject(DataObject.VisibilityOptions.Member, joinCode)},
    25.                 //{Constants.GameTypeKey, new DataObject(DataObject.VisibilityOptions.Public, data.Type.ToString(), DataObject.IndexOptions.N1)},
    26.                 //{Constants.DifficultyKey, new DataObject(DataObject.VisibilityOptions.Public, data.Type.ToString(), DataObject.IndexOptions.N2)}
    27.             }
    28.         };
    29.        
    30.         _currentLobby = await Lobbies.Instance.CreateLobbyAsync(data.LobbyName, MAX_PLAYERS, lobbyOptions);
    31.  
    32.         Transport.SetHostRelayData(relayHostData.IPv4Address, relayHostData.Port, relayHostData.AllocationIDBytes, relayHostData.Key, relayHostData.ConnectionData);
    33.  
    34.         Heartbeat();
    35.         PeriodicallyRefreshLobby();
    36.         Debug.Log($"Lobby Created; Lobby Code: {_currentLobby.LobbyCode}; Relay Code: {joinCode}");
    37.     }
    38.  
    39.   public static async Task JoinLobbyWithAllocation(string lobbyId) {
    40.             _currentLobby = await Lobbies.Instance.JoinLobbyByIdAsync(lobbyId);
    41.            
    42.             var a = await RelayService.Instance.JoinAllocationAsync(_currentLobby.Data[Constants.RelayJoinKey].Value);
    43.  
    44.             Transport.SetClientRelayData(a.RelayServer.IpV4, (ushort)a.RelayServer.Port, a.AllocationIdBytes, a.Key, a.ConnectionData, a.HostConnectionData);
    45.  
    46.             PeriodicallyRefreshLobby();
    47.         }
    NetworkManager.png
    StartedThroughNetworkManager.png StartedThroughScript.png
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,019
    That is the round-trip-time (RTT aka "ping") to the nearest backbone of your ISP or a big network hub in your area. This will almost always be the most optimistic ping you can get to any location on the net.

    You have to measure the RTT to the relay server you're connecting with! RTTis always the time from your computer to some specific other computer over a network, so it depends on what other end you're pinging.

    It looks like that relay server is reachable only with a RTT of 80-120 ms for you. Depending on where you are in the world in relation to the relay server you're connecting to and whether you connect to the Internet via cable or Wifi, that RTT could be either regarded as high or quite good actually.

    You should maybe try to have someone test the RTT to the relay server on their end, and they shouldn't be in the same area as you, to see with what RTT they'll end up with.

    And yes, when connecting through a relay, the relay does what its name implies: it relays information, or data packets, between two connected endpoints. So all traffic is going through the relay. I'm not sure if Unity's Relay server also checks if direct connection or NAT punchthrough can be established between two endpoints, but I think I remember reading that it (currently) does not.
     
    UnityKip likes this.
  3. Sycab

    Sycab

    Joined:
    Jul 11, 2020
    Posts:
    10
    Thank's for your clarifications. I am aware that the "browser" ping is not what to expect from connecting to Unity Servers and that ISP's also do not pick the fastest route depending on the contract Unity has with them.
    Nonetheless the ping of 80-120ms seems relatively high to me. I could also test the client in my university, which is still roughly in the same area, but is in the broadband education network and therefore has very good internet speeds. There I could get a ping of 50ms.
    The region that gets picked when starting the host is Europe-west4. From the Unity Doc I assume this is the Netherlands server, so maybe this ping is just the best I can do, especially if you account for non-ideal ISP routing. ( I'm in Germany)

    If anyone else has experience with what ping one can expect from Unity's Relay Service please let me know. :)
     
  4. UnityKip

    UnityKip

    Unity Technologies

    Joined:
    Nov 15, 2021
    Posts:
    36
    Hi @Sycab

    I'm chiming in here to build on what @CodeSmile has said to give you some additional clarity.

    First, your original test looks to be done with NGO (Netcode for Game Objects) with the client's server target set to 127.0.0.1. Since your host is running locally, NGO will be creating the client connection to the local machine on the loopback address. Any ping above that 5-10 ms range would be highly suspect and your experience is expected.

    You can test your ping via command line using something similar to:
    ping 127.0.0.1


    Next, as mentioned by @CodeSmile , Relay forwards all information from a client to a relay server which then forwards it to the host. In NGO, you should see your client's Connection Data (under the Unity Transport component of the Network Manager) update the Address and Port to a Relay server once connected to a Relay allocation. You can ping (as the above) the IP address in the Address field to get an idea of what your RTT might look like as an actual client. Alternatively, you can check the IP address of a given allocation by looking at allocation.RelayServer.IpV4 after an allocation has been assigned. This is all to say that a ping of 80-120 ms is probably within normal bounds for the service whereas 5-10 ms is not likely to be possible for the vast majority of users.

    Finally, please note that Relay does not currently have a way to "short circuit" the relay for LANs or topologies that might benefit from using multiple relays. However, this feature is currently Under Consideration on our roadmap (you'll need to choose the Relay subsection/tab on the roadmap) through the Support Multiple Topologies card. If this (or any other) feature would be useful to you, you can click on the card and vote for it! Any feedback you provide there will be sent to our product teams for review.

    -Kip
     
    CodeSmile likes this.
  5. Sycab

    Sycab

    Joined:
    Jul 11, 2020
    Posts:
    10
    Hi Kip,

    thank you for your detailed explanation. :)

    For me the ip address in the inspector of Unity Transport does not change on starting a host/client and stays at the localhosts address. However console logging the ip address of the allocation does work, but I just wanted to mention it for completeness sake.

    Pinging the relay server from my console results in request timeouts and the server receives 0 packets. So measuring my ping to the server that way does not seem to work.
     
Thread Status:
Not open for further replies.