3

[I work in c#]

In order to decide weather a device should become a server with local client or client alone (for main-server-less networking) I need to find out if there are any other available servers for that device before turning into a server with local client if not for another client device to join by either receiving NetworkDiscovery broadcasts from a server or not - currently I can't get a client to receive broadcast from a server.

I have created two empty gameobjects each with scripts, one script makes it a server and should be broadcasting from its NetworkDiscovery via NetworkDiscovery.StartAsServer() but currently one my client whose NetworkDiscovery has been set to NetworkDiscovery.StartAsClient() is not getting theOnRecievedBroadcast() function called hence not receiving broadcasts from the server.

The two scripts shown below are the client and server:

Client -

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class SearchForServers : MonoBehaviour {
    bool serverIsFound;
    NetworkDiscovery NetworkDiscovery;
    // Use this for initialization
    void Start () {
        serverIsFound = false;
        NetworkClient Client = new NetworkClient();
        NetworkDiscovery = gameObject.AddComponent<NetworkDiscovery>();
        NetworkDiscovery.Initialize();
        NetworkDiscovery.StartAsClient();
    }

    void OnRecievedBroadcast(string fromAdress, string data)
    {
        serverIsFound = true;
    }

    // Update is called once per frame
    void Update () {
        Debug.Log("Server Found = " + serverIsFound);
    } 
}

Server -

    using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class CreateServer : MonoBehaviour
{
    bool create;
    int minPort = 10000;
    int maxPort = 10010;
    int defaultPort = 10000;
    NetworkDiscovery NetworkDiscovery;

    void Start()
    {
        create = true;
        if (create == true)
        {
            int serverPort = createServer();
            if (serverPort != -1)
            {
                Debug.Log("Server created on port : " + serverPort);
            }
            else
            {
                Debug.Log("Failed to create Server");
            }
        }
        NetworkDiscovery = gameObject.AddComponent<NetworkDiscovery>();
        NetworkDiscovery.Initialize();
        NetworkDiscovery.StartAsServer();
    }


    //Creates a server then returns the port the server is created with. Returns -1 if server is not created
    int createServer()
    {
        int serverPort = -1;
        //Connect to default port

      bool serverCreated = NetworkServer.Listen(defaultPort);
        if (serverCreated)
        {
            serverPort = defaultPort;
            Debug.Log("Server Created with default port");
        }
        else
        {
            Debug.Log("Failed to create with the default port");
            //Try to create server with other port from min to max except the default port which we trid already
            for (int tempPort = minPort; tempPort <= maxPort; tempPort++)
            {
                //Skip the default port since we have already tried it
                if (tempPort != defaultPort)
                {
                    //Exit loop if successfully create a server
                    if (NetworkServer.Listen(tempPort))
                    {
                        serverPort = tempPort;
                        break;
                    }

                    //If this is the max port and server is not still created, show, failed to create server error
                    if (tempPort == maxPort)
                    {
                        Debug.LogError("Failed to create server");
                    }
                }
            }
        }
        return serverPort;
    }
}

These are the console logs with the debug logging

enter image description here

Thanks for reading I hope that you can realise where I have gone wrong or indeed how to complete said task otherwise. @Programmer

g_l
  • 201
  • 1
  • 6
  • 15
  • Just for anyone googling here. Regarding Unity's "new" networking. Discovery is now built-in and "relatively" easy in the Unity way of things. **Here's a long post with all the code needed to do it exactly** https://forum.unity.com/threads/networkmanager-error-server-client-disconnect-error-1.439245/#post-3754939 – Fattie Nov 25 '18 at 04:31

1 Answers1

3

First of all you named each server and client script the-same name. You don't need OnRecievedBroadcast in the server code. You only need it in the client code. OnRecievedBroadcast is not being called on the client side because you did not override NetworkDiscovery. You must override it.

Here is a simple Discovering Code:

Client:

public class NetClient : NetworkDiscovery
{

    void Start()
    {
        startClient();
    }

    public void startClient()
    {
        Initialize();
        StartAsClient();
    }

    public override void OnReceivedBroadcast(string fromAddress, string data)
    {
         Debug.Log("Server Found");
    }
}

Server:

public class NetServer : NetworkDiscovery
{
    // Use this for initialization
    void Start()
    {
        Application.runInBackground = true;
        startServer();
    }

    //Call to create a server
    public void startServer()
    {
        int serverPort = createServer();
        if (serverPort != -1)
        {
            Debug.Log("Server created on port : " + serverPort);
            broadcastData = serverPort.ToString();
            Initialize();
            StartAsServer();
        }
        else
        {
            Debug.Log("Failed to create Server");
        }
    }

int minPort = 10000;
int maxPort = 10010;
int defaultPort = 10000;

//Creates a server then returns the port the server is created with. Returns -1 if server is not created
private int createServer()
{
    int serverPort = -1;
    //Connect to default port
    bool serverCreated = NetworkServer.Listen(defaultPort);
    if (serverCreated)
    {
        serverPort = defaultPort;
        Debug.Log("Server Created with deafault port");
    }
    else
    {
        Debug.Log("Failed to create with the default port");
        //Try to create server with other port from min to max except the default port which we trid already
        for (int tempPort = minPort; tempPort <= maxPort; tempPort++)
        {
            //Skip the default port since we have already tried it
            if (tempPort != defaultPort)
            {
                //Exit loop if successfully create a server
                if (NetworkServer.Listen(tempPort))
                {
                    serverPort = tempPort;
                    break;
                }

                //If this is the max port and server is not still created, show, failed to create server error
                if (tempPort == maxPort)
                {
                    Debug.LogError("Failed to create server");
                }
            }
        }
    }
    return serverPort;
}
}

The createServer() function is a function from your last question. I don't think you can have both server and client code running at the-same time in the Editor.

For testing, you must build the code in your pc with the server code/NetServer enabled. Run the built program then from your Editor you can run the client/NetClient code. This should discover game on the server.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • Sorry my mistake I do made a foolish copy and paste mistake, I did have different scripts, I'll update it – g_l Jul 30 '16 at 17:55
  • Still I realise I was far off, feel free to not answer if my attempted code does not make sense – g_l Jul 30 '16 at 18:13
  • @g_l I see your update. Modify your script to override from `NetworkDiscovery` instead of `MonoBehaviour`. Also replace `void OnRecievedBroadcast(string fromAdress, string data)` with `public override void OnReceivedBroadcast(string fromAddress, string data)`. You were so close. The overriding stuff you missed. After overriding, Replace `NetworkDiscovery.Initialize();` and `NetworkDiscovery.StartAsClient();` with `Initialize();` and `StartAsClient();`. Do the-same thing for the server code too. – Programmer Jul 30 '16 at 18:18
  • Also keep checking back. I will update this question with complete client/server discovery. Unet is still new and examples are too hard to find. Writing one here will help others. – Programmer Jul 30 '16 at 18:19
  • 1
    Also `Update ()` function the `SearchForServers` script. If you have that, `OnReceivedBroadcast` wont be called. This is very important.. – Programmer Jul 30 '16 at 18:32
  • Thanks @Programmer all this is good to know, indeed hopefully this can be an example for those using this form of networking in the future – g_l Jul 30 '16 at 18:44
  • reading the documentation this only works when both devices are on the same LAN so how could a client see if there was a sever anywhere from the same game connected to the internet? (Is this a separate question?) @Programmer – g_l Jul 31 '16 at 10:23
  • @g_l **port-forwarding/NAT**. Already answered here http://stackoverflow.com/a/36092168/3785314. Just find a free C# port forwarding library to open the port then send the ip and port to your server. That server is where every player connects to, to see available games. Note that you can do this with Unity's built in API but you have to pay. That's why the question I linked is very important. Anyways, I am still working to update this post with simple client discovery.. – Programmer Jul 31 '16 at 10:33
  • Checking it out @Programmer – g_l Jul 31 '16 at 10:36
  • Would I be able to solve my problem by leaving a device with server on 24/7 which all devices could join to begin with then the server would identify pairs and give them the info for them to join up? This would avoid the complexity of said above @Programmer – g_l Jul 31 '16 at 10:45