Search Unity

Question NGO: How can I connect with multiple servers?

Discussion in 'Multiplayer' started by blakstar123, Mar 22, 2024.

  1. blakstar123

    blakstar123

    Joined:
    Nov 7, 2023
    Posts:
    9
    Hi all,

    For a research purpose, I'd like to connect with two servers for a single clients.(testing with Boss Room)
    One for normal remote server(or host), and another for local server within same device(runs as separate process)

    Specifically, what I want is like...

    1) ServerRPC
    - Send RPC request to both local server and remote server

    2) ClientRPC
    - Client should be able to receive ClientRPC for both servers. No need to distinguish which server request for it.

    To do so, I need to setup connect for both servers. I tried to declare two NetworkManager and try to connect for both server with StartClient(), but it seems not working...

    How do I achieve this? If NGO does not offer this feature, is there any simple way to bypass it?
     
    Last edited: Mar 22, 2024
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,012
    Afaik this isn‘t possible with NGO.

    It may be possible if you rely solely on Unity Transport layer. But you need to be aware that you are entering completely new territory. You will hardly get any support or find any info for this from anyone. You will have to do a deep dive research and be ready to inspect and understand at least the transport code.

    What are you trying to achieve with this anyway? Perhaps there is an easier solution, like synchronizing state with a database via webrequest. You could also have the server write directly to a database, local or remote.
     
  3. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    666
    What you're attempting should be possible, I had two separate network managers running in a project a while ago. I was initially having problems and I contacted Simon Lemay who saw no reason why it shouldn't work and it turned out the issues were just down to me.

    I've just tried it with v1.8.1 of NGO in a test project with two ParrelSync clones acting as servers and for connecting at least there's no apparent issues. Something to keep in mind is that for what I was doing I was only using custom messaging and didn't have to worry about network objects and scene changes. I don't know much about Boss Room but if it's using the default scene management to synchronise the scenes and objects modifying it to allow a client to connect to two server instances simultaneously could get really complicated. I wouldn't be brave enough to try using that project for this sort of testing.

    Here's my test project code in case it helps, it does no more than allow the client to connect to both servers.

    Code (CSharp):
    1.     public class DualNetworkManagersSceneController : MonoBehaviour
    2.     {
    3.         void Start()
    4.         {
    5.             Application.targetFrameRate = 15;
    6.  
    7.             if (!ClonesManager.IsClone())
    8.             {
    9.                 SceneManager.LoadScene("ClientScene");
    10.             }
    11.             else
    12.             {
    13.                 SceneManager.LoadScene("ServerScene");
    14.             }
    15.         }
    16.     }
    Code (CSharp):
    1.     public class ClientSceneController : MonoBehaviour
    2.     {
    3.         [SerializeField] NetworkManager networkLocal;
    4.         [SerializeField] NetworkManager networkRemote;
    5.  
    6.  
    7.         private void Start()
    8.         {
    9.             networkLocal.StartClient();
    10.             networkRemote.StartClient();
    11.         }
    12.     }
    Code (CSharp):
    1.     public class ServerSceneController : MonoBehaviour
    2.     {
    3.         [SerializeField] NetworkManager networkManager;
    4.  
    5.         private void Start()
    6.         {
    7.             UnityTransport transport = (UnityTransport)networkManager.NetworkConfig.NetworkTransport;
    8.  
    9.             transport.SetConnectionData("127.0.0.1", ushort.Parse(ClonesManager.GetArgument()));
    10.             networkManager.StartServer();  
    11.         }
    12.     }
    One thing to look out for if you are having issues is make sure you have no references to NetworkManager.Singleton on the client, as there'll be two network managers running it's no longer a valid or useful reference.
     
    Last edited: Mar 22, 2024
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,012
    Uhm ... question: when the server calls a [RPC(SendTo.Client)] method, which transport is this message routed through? Both?

    Unless Netcode is clever enough about this you may be doubling the server's outgoing traffic. Or it may seemingly at random not work because the RPC is sent through the other transport not meant for client communication. This could possibly depend on execution order.
     
  5. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    In theory, in that scenario the RPC would be routed through the network manager that spawned the object on which the RPC is invoked. Now that's theory. In practice running multiple network managers is not really supported, so it might end up routing through
    NetworkManager.Singleton
    as a fallback (which could be either instance depending on instantiation order).

    In general I'd recommend against trying to run multiple network managers like that. For some use cases it will likely work fine (e.g. if only using custom messages as stated above), but there's likely other features still relying on the singleton to work and those would be broken in that scenario.

    If using Unity Transport directly, you can run multiple network drivers at the same time and that use case is fully supported. But you'll be dealing with a much lower level API compared to NGO.
     
    cerestorm and CodeSmile like this.
  6. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    666
    Makes sense. I switched over from NGO to Unity Transport as it was a better fit for the requirements of the project and I didn't have a worry about any possible conflicts.
     
  7. blakstar123

    blakstar123

    Joined:
    Nov 7, 2023
    Posts:
    9
    Thanks all.

    So, keeping multiple NetworkManager is not appropriate for most cases as every noted here.
    However, I guess swtiching both connection into Unity Transport takes too much time...

    So, how about using 3rd party solution for local server, while keeping NGO NetworkManager connection for remote server?
    Local server should be runs in NGO server mode, to keep game states. But I think it's possible to run as gRPC server or Mirror server at the same time.

    To do so, impls should be detached on RPC methods.



    Code (CSharp):
    1.         [ServerRpc]
    2.         public void RecvDoActionServerRPC(ActionRequestData data)
    3. {
    4.     RecvDoActionServerRPCImpl(data);
    5. }
    This is an original ServerRPC that detached with implementation codes.

    Code (CSharp):
    1.         [3rdPartyRPC]
    2.         public void RecvDoActionServerRPCThirdParty(ActionRequestData data)
    3. {
    4.     RecvDoActionServerRPCImpl(data);
    5. }
    This is a new delegate method for 3rd party rpc solutions like gRPC or Mirror.

    Code (CSharp):
    1.      
    2.         public void RecvDoActionServerRPCImpl(ActionRequestData data)
    3. {
    4.     // actual implementation moved here
    5. }

    Is this approach works? or any other more simple solution...?