Search Unity

Feature Request netcode Network Discovery

Discussion in 'Netcode for GameObjects' started by liambilly, Mar 4, 2023.

  1. liambilly

    liambilly

    Joined:
    May 13, 2022
    Posts:
    154
    Last edited: Mar 5, 2023
    francisIsFine likes this.
  2. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    I rewrote the NetworkDiscovery component shipped with UNET in the past and it worked with the UnetTransport for some time. However since Netcode 1.1.0 and using UnityTransport, basic broadcasting support seems to be broken even with all firewalls disabled. With the working, previous code, neither sending nor processing incoming broadcast messages could be done, after hours trying to work something out.

    So, I just assume that the underlying technique of the NetworkDiscovery component is faulty. That's why I have thrown the old implementation away and rewrote it using the UdpClient .NET class and .send, which does work e.g. with one PC connected via LAN and a Macbook connected via WiFi on the same router (still requires disabling firewalls). It did that in my asset Tanks Multiplayer.
    http://forum.unity3d.com/threads/410465/
     
  3. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    Could you please open a feature request here? In this way, the team behind Netcode For GameObject will be able to prioritize your features, and you'll be automatically updated about their status
     
  4. liambilly

    liambilly

    Joined:
    May 13, 2022
    Posts:
    154
    yeah i tried it, the buttons appear but on pressing them it doesnt discover host on client or cllient on host
     
  5. antnasce

    antnasce

    Joined:
    Apr 27, 2019
    Posts:
    12
    I'm also having issues with Network Discovery. I'm able to do the following:

    Start Server on iOS, macOS can discover the iPhone server and connect on the same WiFi network.

    but not the other way around (start server on Mac, try to connect iPhone to Mac Server), does not work.
     
    francisIsFine likes this.
  6. francisIsFine

    francisIsFine

    Joined:
    Jun 26, 2018
    Posts:
    40
    @antnasce, I've just run into this exact issue. Have you found a solution?
     
    unnanego likes this.
  7. mc_fragezeichen

    mc_fragezeichen

    Joined:
    Aug 17, 2020
    Posts:
    14
    I'm having the same issue. My current (unstable) solution looks like this:
    - host device starts a UDP server, which sends packages via every network adapter to everyone in the same LAN
    - client device starts a UDP client, which listens to the same port as the host
    - when the client receives a package, it parses the sender IP address from it
    - this ip is used to configure the NetworkManager of Unitys NGO package
    - then the client starts with that IP using `NetworkManager.Singleton.StartClient()`

    However, whenever I try to leave a multiplayer session and try to start a second one. I get an error saying: "An application is already bound to the port...". So I need to figure out. Why my cleanup functions are not working properly.


    Here are my Udp classes:



    public class UdpServer : MonoBehaviour
    {
    private UdpClient udpClient;
    private int port = 7778;
    private float sendInterval = 1.0f; // Time in seconds between each packet
    private Coroutine sendCoroutine;
    private void OnEnable()
    {
    udpClient = new UdpClient();
    udpClient.EnableBroadcast = true;
    sendCoroutine = StartCoroutine(SendDataPeriodically());
    }
    private void OnDisable()
    {
    if (sendCoroutine != null)
    {
    StopCoroutine(sendCoroutine);
    }
    if (udpClient != null)
    {
    udpClient.Close();
    udpClient = null; // Nullify the udpClient to avoid reuse
    }
    }
    private IEnumerator SendDataPeriodically()
    {
    string message = "MY_GAME_IDENTIFIER";
    while (true)
    {
    try
    {
    byte[] data = Encoding.UTF8.GetBytes(message);
    udpClient.Send(data, data.Length, new IPEndPoint(IPAddress.Broadcast, port));
    }
    catch (Exception e)
    {
    Debug.LogError(e.ToString());
    yield break; // Exit the coroutine if an error occurs
    }
    yield return new WaitForSeconds(sendInterval);
    }
    }
    }




    and for the UDP client



    public class UdpClientListener : MonoBehaviour
    {
    public UnityEvent<string> HostIpReceived;
    private UdpClient udpClient;
    private int port = 7778;
    private bool clientConnectionInitiated;
    private void OnEnable()
    {
    InitializeUdpClient();
    BeginReceive();
    }
    private void InitializeUdpClient()
    {
    clientConnectionInitiated = false;
    // Ensure any existing UdpClient is properly closed before initializing a new one
    if (udpClient != null)
    {
    udpClient.Close();
    }
    udpClient = new UdpClient(port);
    }
    private void BeginReceive()
    {
    try
    {
    udpClient.BeginReceive(ReceiveCallback, null);
    }
    catch (Exception e)
    {
    Debug.LogError("BeginReceive failed: " + e.Message);
    }
    }
    private void ReceiveCallback(IAsyncResult ar)
    {
    if (clientConnectionInitiated)
    {
    return; // Exit if a connection has already been initiated
    }
    IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
    byte[] bytes;
    try
    {
    bytes = udpClient.EndReceive(ar, ref remoteEndPoint);
    }
    catch (Exception e)
    {
    Debug.LogError("ReceiveCallback failed: " + e.Message);
    return;
    }
    string receivedMessage = Encoding.UTF8.GetString(bytes);
    Debug.Log("Received: " + receivedMessage);
    if (IsValidIpAddress(receivedMessage))
    {
    clientConnectionInitiated = true;

    // Extract the sender's IP address
    string senderIP = remoteEndPoint.Address.ToString();
    Debug.Log("Received from IP: " + senderIP);

    // Use the dispatcher to handle the IP address on the main thread
    MainThreadDispatcher.Enqueue(() => HostIpReceived?.Invoke(senderIP));
    }
    BeginReceive(); // Restart receiving if still enabled
    }
    private bool IsValidIpAddress(string ipAddress)
    {
    return IPAddress.TryParse(ipAddress, out _);
    }
    private void OnDisable()
    {
    if (udpClient != null)
    {
    udpClient.Close();
    udpClient = null; // Ensure the UdpClient is nullified to prevent reuse
    }
    }
    }


     
    Last edited: Feb 2, 2024
    unnanego likes this.
  8. unnanego

    unnanego

    Joined:
    May 8, 2018
    Posts:
    199
    Having the same issue with vision os and the community network discovery - it can start a server and receive broadcasts, but not the other way around