Connection events as host/client being the same instance with Network Transport (LLAPI)

I’ve been struggling on how to handle connection events with Network Transport.
The game connects through Unity Matchmaking Services and the client who is creating the game will act as host and client at the same time.
The problem with this is that i’m receiving two connection events from the same client (the host). I suppose one is the server connection and the second is the client connection (also the host).

Here is how i open the socket:

private void OpenSocket(bool host)
{
    // Clear any configured channels
    m_topology.DefaultConfig.Channels.Clear();
    // Setup channels
    m_reliableChannelId = m_topology.DefaultConfig.AddChannel(QosType.Reliable);
    m_unrealiableChannelId = m_topology.DefaultConfig.AddChannel(QosType.Unreliable);

    if (host)
    {
        // Setup host socket
        m_clientSocketId = NetworkTransport.AddHost(m_topology, m_port);
    }

    else
    {
        // Setup client socket
        m_clientSocketId = NetworkTransport.AddHost(m_topology);
    }
}

Here is the method that is called when the match is created by the host. As you can see, im connecting as a host and peer client. If i only connect as a host, i don’t receive any network events, so i don’t understand what is the purpose on NetworkTransport.ConnectAsNetworkHost:

private void OnMatchCreated(bool success, string extendedInfo, MatchInfo matchInfo)
{
    if (success)
    {
        m_matchInfo = matchInfo;
        // Flag as host
        m_isHost = true;

        Utility.SetAccessTokenForNetwork(matchInfo.networkId, matchInfo.accessToken);
        NetworkTransport.Init();
        OpenSocket(true);

        if (m_iterationRoutine != null)
            StopCoroutine(m_iterationRoutine);
        m_iterationRoutine = StartCoroutine(StartNetworkIteration());

        byte berr;
        // I don't understand what is the purpose on this. I'm not receiving any network events if i only connect as a host
        NetworkTransport.ConnectAsNetworkHost(m_clientSocketId, matchInfo.address, matchInfo.port,
            matchInfo.networkId, Utility.GetSourceID(), matchInfo.nodeId, out berr);
        if (Debug.isDebugBuild)
            Debug.Log(string.Format("URealtimeNetwork.OnMatchCreated.ConnectAsNetworkHost({0})", ((NetworkError)berr).ToString()));

        // Also connect as a peer-client. If i don't do this, i don't receive any network events
        m_connectionId = NetworkTransport.ConnectToNetworkPeer(m_clientSocketId, matchInfo.address, matchInfo.port, 0, 0,
            matchInfo.networkId, Utility.GetSourceID(), matchInfo.nodeId, out berr);

        NetworkError error = (NetworkError)berr;
        if (Debug.isDebugBuild)
            Debug.Log(string.Format("URealtimeNetwork.OnMatchCreated.ConnectToNetworkPeer({0})", error.ToString()));

        if (error == NetworkError.Ok)
        {
            RegisterCallbacks();

            if (m_iterationPerSecondRoutine != null)
                StopCoroutine(m_iterationPerSecondRoutine);
            m_iterationPerSecondRoutine = StartCoroutine(IterationPerSecondRoutine());
        }

        else
        {
            success = false;
            // Could not connect, destroy any connection created
            Disconnect();
        }
    }
}

Here is how i handle connection events. As its commented in the code, i’m receiving 2 connection events when the host connects, and complicates the client handling because im registering a new client when is actually the same client:

void Update()
{
    if (m_clientSocketId != -1)
    {
        NetworkEventType receivedEvent = NetworkEventType.Nothing;

        do
        {
            int connectionId, channelId, dataSize;
            receivedEvent = NetworkTransport.ReceiveFromHost(m_clientSocketId, out connectionId, out channelId,
                m_buffer, m_buffer.Length, out dataSize, out error);

            if (receivedEvent == NetworkEventType.ConnectEvent)
            {
                if (isHost)
                {
                    // When the host connects i receive 2 events
                    // which complicates the client handling
                    string customClientId = GenerateNewClientId();
                    RegisterNewClient(connectionId, customClientId);
                }
            }
        }
        while (receivedEvent != NetworkEventType.Nothing);
    }
}

Hm if you receive two connection events I suppose that connectionId should be different? add logs for connectionId. I suppose that in your example m_ConnectionId == 1, while events which you received belongs connectionId = 1 and 2…

Yes, that is what i did. When i get the connection event i skip m_connectionId == 2.
The purpose of my question is to confirm that the example i gave is a doable way to do it, or i’m doing anything wrong. If possible, can you explain what is the purpose on NetworkTransport.ConnectAsNetworkHost ?

If possible, can you explain what is the purpose on NetworkTransport.ConnectAsNetworkHost ?

ok, it’s easy. Imagine, you are going to create the game which will have, say, 6 players one of them is a host.
Pre-game stage looks like:
First player started and advertise itself as host of the game, other player connects to them. When host decided that it is ready to play, game started.

Lets consider the relay server workflow. Note, there is a significant time gap between host-relay connection, and player-relay(-host) connection. During this period relay should know that host is alive, so relay sends periodically keep alive messages to host, if relay find that there is no network activity with host for a time it will close them and will notify MM about match closing.

It is not necessary for generic player as it interchange keep alive packets with host.

Was I clean?

1 Like

Yes, thank you very much.