How to use DriverMigrationSystem (Connect from LocalClientServer to Remote Server)

I would like to achieve the following:

  • Start the game in Client&Server mode.
  • Portals are created for all current Lobby games
  • When the player goes through one of the lobby portals the player should be connected to that remote server

The main issue seems to be the network driver, as when I try to connect to the new server I receive the following error message:
InvalidOperationException: Connection to server already initiated, only one connection allowed at a time.

I did the following for now:

  • Destroy existing client & server worlds
  • Assign new NetworkStreamReceiveSystem.DriverConstructor with obtained relay information
  • Create a fresh client world or client & server (for the host) using that constructor

The problem is that doesn’t seem to work properly. After the exception the connection is not properly established.

Code

     var world = World.All[0];
     for (int i = World.All.Count - 1; i >= 0; i--) {
       var previousWorld = World.All[i];
       if (previousWorld.IsClient() || previousWorld.IsServer()) {
         previousWorld.Dispose();
       }
     }
     var relayStuff = SystemAPI.GetSingleton < EnableRelayServer > ();
     var relayClientData = world.GetExistingSystemManaged < ConnectingPlayer > ().RelayClientData;
     var relayServerData = world.GetExistingSystemManaged < HostServer > ().RelayServerData;
     var joinCode = world.GetExistingSystemManaged < HostServer > ().JoinCode;
     var createLobbyEntity = EntityManager.CreateEntity();
     EntityManager.AddComponentData(createLobbyEntity, new CreateLobbyRequest() {
       joinCode = joinCode,
         lobbyName = $ "CubeTest_{Random.Range(0, 10_000)}",
         maxPlayers = 4
     });
     var oldConstructor = NetworkStreamReceiveSystem.DriverConstructor;
     NetworkStreamReceiveSystem.DriverConstructor = new RelayDriverConstructor(relayServerData, relayClientData);
     var server = ClientServerBootstrap.CreateServerWorld("ServerWorld");
     SceneSystem.LoadSceneAsync(server.Unmanaged, relayStuff.sceneReference);
     var client = ClientServerBootstrap.CreateClientWorld("ClientWorld");
     SceneSystem.LoadSceneAsync(client.Unmanaged, relayStuff.sceneReference);
     NetworkStreamReceiveSystem.DriverConstructor = oldConstructor;
     if (World.DefaultGameObjectInjectionWorld == null)
       World.DefaultGameObjectInjectionWorld = server;
     ref
     var joinCodeComponent = ref SystemAPI.GetSingletonRW < JoinCode > ().ValueRW;
     joinCodeComponent.value = joinCode;
     var networkStreamEntity = server.EntityManager.CreateEntity(ComponentType.ReadWrite < NetworkStreamRequestListen > ());
     server.EntityManager.SetName(networkStreamEntity, "NetworkStreamRequestListen");
     server.EntityManager.SetComponentData(networkStreamEntity,
       new NetworkStreamRequestListen {
         Endpoint = NetworkEndpoint.AnyIpv4
       });
     networkStreamEntity
       = client.EntityManager.CreateEntity(ComponentType.ReadWrite < NetworkStreamRequestConnect > ());
     client.EntityManager.SetName(networkStreamEntity, "NetworkStreamRequestConnect");
     // For IPC this will not work and give an error in the transport layer. For this sample we force the client to connect through the relay service.
     // For a locally hosted server, the client would need to connect to NetworkEndpoint.AnyIpv4, and the relayClientData.Endpoint in all other cases.
     client.EntityManager.SetComponentData(networkStreamEntity,
       new NetworkStreamRequestConnect {
         Endpoint = relayClientData.Endpoint
       });

I found the DriverMigrationSystem, but when using it (storing and loading the worlds) nothing actually seemed to work.

Is there currently a possibility to start with a Client&Server world, and then connect to a remote server with the relay system?

Just missed setting the ClientServerBootstrap.AutoConnectPort to 0.