UNET NetworkServer listen of multiple ports

Hi All!

I am working on dedicated server, lately I was working on admin tool for server. This tool should be able to connect and control server. I was hoping that I could open two ports (or more) for different kinds of connections (one for clients, other for admin stuff, etc.). But when I invoke Listen(port) command for second time - all messages that come from first registered port are received, but no handlers are called in response.

How is that possible? I get no errors, nothing, just no response for everything that comes from first registered port. Everything works fine on second port though. Is there a way to make NetworkServer listen to more than one port?

Calling Listen a second time on the same NetworkServer is probably not what you want to do. I would expect that to shut down the first server and start a new one but it seems like you’re seeing even weirder behaviour.

The way I do this is by starting a separate NetworkServerSimple on the second port. Whenever I get an incoming connection on the simple server I add it to the default NetworkServer using NetworkServer.AddExternalConnection

    public class ExternalServer : NetworkServerSimple
    {
        // Call SetNetworkConnectionClass() so the ExternalNetworkConnection calls is used for connections to this server.
        public override void Initialize()
        {
            base.Initialize();

            // Use the custom connection class to prevent connectionId conflicts
            SetNetworkConnectionClass<ExternalNetworkConnection>();
        }

        // Adds the incoming connection to NetworkServer via AddExternalConnection
        public override void OnConnected(NetworkConnection conn)
        {
            base.OnConnected(conn);

            NetworkServer.AddExternalConnection(conn);
        }

        public override void OnDisconnected(NetworkConnection conn)
        {
            base.OnDisconnected(conn);

            NetworkServer.RemoveExternalConnection(conn.connectionId);
        }
    }

I also had to create my own ExternalNetworkConnection class because the connectionId needs to be offset to not collide with the default NetworkServer’s own connections (the ones connecting on the first port). It looks something like this:

    public class ExternalNetworkConnection : NetworkConnection
    {
        private int offset;
      
        // Adds an offset to the connectionId
        public override void Initialize(string networkAddress, int netHostId, int netConnId, HostTopology hostTopology)
        {
            // This is pretty ugly but I just couldn't think of a better way
            // NetworkConnections really should not be dependent on the NetworkServer like this but *shrug*
            offset = NetworkServer.hostTopology.MaxDefaultConnections * netHostId;
            base.Initialize(networkAddress, netHostId, netConnId + offset, hostTopology);
        }

        // Un-offsets the connectionId to get the id of the connection on the ExternalServer
        public override bool TransportSend(byte[] bytes, int numBytes, int channelId, out byte error)
        {
            return NetworkTransport.Send(hostId, connectionId - offset, channelId, bytes, numBytes, out error);
        }
    }

Pretty sure I stole that basic idea from somewhere else on the forums but who knows where at this point.

1 Like

What do you mean by “starting a separate NetworkServerSimple on the second port” . How i set the second port i want using ExternalServer if there is not a listen method to specify the port? Also its not derived from monobehaviour so i cant add it to scene to listen for a port

There is: https://docs.unity3d.com/ScriptReference/Networking.NetworkServerSimple.Listen.html

It’s just a regular class:

var newServer = new ExternalServer();
newServer.Listen(listenPort);

You’ll also need to make sure to constantly Update the server from some Update() method

newServer.Update();

Thanks, i didnt read well and thought you didnt use listen, just dont use listen twice in the same, so i didnt see how you listened to the port, but i tried that after i asked you and didnt work, i am using an Ubuntu server and it gives me the error “Segmentation fault (core dumped)” and process crash

I tried your code but using the structure shown in WebGL and mobile cross platform uNet server where create an instance of NetworkServerSimple and doesnt give the segmentation fault error but client doesnt connect.

I am using a custom networkmanager component using websockets and this script in the same gameobject in server without websockets enabled for NetworkServerSimple server and in client i call use
localClient = new NetworkClient();
localClient.Connect(access.RoomIp, 7777);

I finally made it work, i had the firewall ports of my servers wrong configured and they were blocking the connection

1 Like