When attempting to connect a client to my Relay host, I get the status code error:
Networking.Transport.Error.StatusCode.NetworkStateMismatch
The human readable translation is:
“Sending data while connecting on connection {0} is not allowed.”;
What are the possible causes of this error? I get this error even when running the instance on separate machines - one is my Smartphone with WiFi disconnected, so I’ve ruled out bottlenecks on the same router.
The most common cause for this error is attempting to send data on a connection that is not in the connected state (either because it’s in the process of being established, or because it has been disconnected).
Are you using Netcode for GameObjects? If so, which version?
I’m using version 1.0.2
The join code is:
private async Task JoinEvent(string q_string)
{
RelayManager.RelayJoinData joinData;
joinData = await RelayManager.JoinGame(q_string);
eventCodeText.text = “Success”;
codeInputObject.SetActive(false);
//Retrieve the Unity transport used by the NetworkManager
UnityTransport transport = NetworkManager.Singleton.gameObject.GetComponent();
// Establish the allocation data to use Relay
transport.SetClientRelayData(joinData.IPv4Address, joinData.Port, joinData.AllocationIDBytes, joinData.Key, joinData.ConnectionData, joinData.HostConnectionData);
// Start this instance as the Host
bool worked = false;
worked = networkManager.StartClient();
if (worked)
eventCodeText.text = “Client established”;
else
eventCodeText.text = “Client did not establish”;
}
(eventCodeText is a local TextMeshPro used for real-time display without having to look at the Debug.Log results) - The “Client established” confirmation displays, but NetworkManager.ConnectedClientsList.Count doesn’t change and the error occurs when trying to use a ServerRpc.
Ah I see. I think there might be a misunderstanding about what StartClient
does. If it returns successfully, it only means that the connection process has been successfully started. It doesn’t mean that the connection has been fully established yet (I know, it’s a bit counter-intuitive).
If you want to know when the connection is ready, you can register a OnClientConnectedCallback
on the NetworkManager
. This will let you know when the connection has been fully established. Only after this callback is invoked is it safe to send RPCs and other messages.
That makes sense, but it’s revealed a different problem - the host code seems to become invalid after a short time. If I enter the code quickly and try to connect a client, the StartClient returns true but then gets no further. If I wait somewhere between 8-10 seconds, StartClient returns false. I need to figure out if there’s something else I need to do to keep the connection by the host active.
This is all the host connection code. I assumed that binding happened behind the curtain, but is there something else I need here?
private async Task LaunchHost()
{
RelayManager.RelayHostData hostData;
hostData = await RelayManager.HostGame(4);
eventCodeText.text = "Code: " + RelayManager.hostCode;
roomManager.PopulateRosters();
//Retrieve the Unity transport used by the NetworkManager
UnityTransport transport = NetworkManager.Singleton.gameObject.GetComponent();
// Establish the allocation data to use Relay
transport.SetHostRelayData(hostData.IPv4Address, hostData.Port, hostData.AllocationIDBytes, hostData.Key, hostData.ConnectionData);
// Start this instance as the Host
networkManager.StartHost();
}
Once the host is started it should keep the connection alive on its own (as long as the network manager keeps being updated). Have you checked that StartHost
succeeds?
Yes, I’m getting a 6-character join code and the return value is true, confirmed by:
// Start this instance as the Host
bool worked = false;
worked = networkManager.StartHost();
if (worked)
eventCodeText.text += “\nConnected”;
else
eventCodeText.text += “\nFailed”;
What is the value of the “Hearbeat Timeout Ms” setting under the “Unity Transport” component?
Also, have you checked that the isSecure
parameter of SetClientRelayData
and SetHostRelayData
matches that of the endpoint you selected from the Relay allocation? For example, if you select the endpoint with connection type “dtls”, you should set the isSecure
parameter to true.
Brilliant - setting isSecure to true solved the problems! SetClientRelayData and SetHostRelayData were defaulting to a false value for isSecure. Forcing to true worked.
For reference, Heartbeat Timeout MS is unchanged from the default 500.
Thanks