Hi all,
I’ve been working on supporting secure Websockets (WSS) for a N4E-based application. This is to ensure the app works in restrictive firewall environments.
We have Unity Relay working for client-hosted sessions using WSS. Now I am trying to do the same for a dedicated server mode.
The advice I’ve been able to find online is, either implement a reverse proxy with proper certificates or use Unity Relay in front of the dedicated server.
I didn’t have much luck with the reverse proxy, so now I am trying to get our server to connect as a host on Relay. Only, the client connections time out. This is confusing, as I am using near-identical code as we use for client-hosted sessions, which we confirm to be working well.
Is there anything I need to know about the Multiplay Hosting context, like network restrictions or any specific steps I need to carry out to make it work with dedicated servers?
On the server, we perform boot processes and start hosting. High-level, this is what happens next:
// 1. Allocate Relay server and obtain Join Code
var allocation = await _relayService.CreateAllocation(_lifecycleSettings.MaxPlayers);
string joinCode = await _relayService.GetJoinCode(allocation.AllocationId);
// 2. Register Relay network driver constructor
var serverRelayData = new RelayServerData(allocation, "wss");
var driverConstructor = new RelayNetworkDriverConstructor(serverData: serverRelayData);
NetworkStreamReceiveSystem.DriverConstructor = driverConstructor;
// ... Under the hood: RelayNetworkDriverConstructor.CreateServerDriver
var settings = DefaultDriverBuilder.GetNetworkSettings();
settings = settings.WithRelayParameters(ref _relayServerData);
DefaultDriverBuilder.RegisterServerWebSocketDriver(world, ref driverStore, netDebug, settings);
// 3. Set up server world and transition to scene
var serverWorld = ClientServerBootstrap.CreateServerWorld("ServerWorld");
await _ourSceneSwitchingLogic.LoadSessionSceneAsync();
// 4. Start listening for client connections
var endpoint = NetworkEndpoint.AnyIpv4.WithPort(serverRelayData.Endpoint.Port);
var listenRequest = serverWorld .EntityManager.CreateEntity(typeof(NetworkStreamRequestListen));
serverWorld.EntityManager.SetComponentData(listenRequest, new NetworkStreamRequestListen { Endpoint = endpoint });
On the client, when joining a server, we do something like:
// 1. Join the allocation using code
var joinAllocation = await _relayService.JoinAllocation("Join code from server");
// 2. Register Relay network driver constructor
var clientRelayData = new RelayServerData(joinAllocation, "wss");
var driverConstructor = new RelayNetworkDriverConstructor(clientData: clientRelayData);
NetworkStreamReceiveSystem.DriverConstructor = driverConstructor;
// ... Under the hood: RelayNetworkDriverConstructor.CreateClientDriver
var settings = DefaultDriverBuilder.GetNetworkSettings();
settings = settings.WithRelayParameters(ref _relayClientData);
DefaultDriverBuilder.RegisterServerWebSocketDriver(world, ref driverStore, netDebug, settings);
// 3. Set up client world and transition to scene
var clientWorld = ClientServerBootstrap.CreateClientWorld("ClientWorld");
await _ourSceneSwitchingLogic.LoadSessionSceneAsync();
// 4. Connect to Relay server
var connectRequest = clientWorld .EntityManager.CreateEntity(typeof(NetworkStreamRequestConnect));
clientWorld .EntityManager.SetComponentData(connectRequest, new NetworkStreamRequestConnect { Endpoint = clientRelayData .endpoint });
What happens next is nothing. No errors until the connection eventually times out.
I’ve confirmed the network driver setup to work for client-hosted sessions. Servers work when we do standard UDP connect as well.
My suspicion is something is going on in the Multiplay hosted context that’s different from client builds, but I am struggling to narrow down what.
Any ideas? Is there something I’m doing wrong?