Search code examples
c#unity-game-engineunity-webgl

Unity coroutine not working as expected with WebRequest


This code is logging the token immediately after the web request when it should wait for the variable to be set. Here's the code:

public void ConnectToLiveKit(string Username, string RoomName){

        string query = $"?roomname={RoomName}&username={Username}";
        string fullUri = ServiceURL+query;
        StartCoroutine(GetToken(fullUri));
        Debug.Log($"Token: {m_Token}");
        // handle NO TOKEN here
        StartCoroutine(CreateOrJoinRoom(Username, RoomName));
    }

    IEnumerator GetToken(string uri)
    {
        Debug.Log("Getting Token at " + uri + " ...");
        // using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
        // {
            UnityWebRequest webRequest = UnityWebRequest.Get(uri);
            // Request and wait for the desired page.
            yield return webRequest.SendWebRequest();
            // while (!webRequest.result.Equals(UnityWebRequest.Result.Success)){
            //     yield return new WaitForEndOfFrame();
            // }

            string[] pages = uri.Split('/');
            int page = pages.Length - 1;

            switch (webRequest.result)
            {
                case UnityWebRequest.Result.ConnectionError:
                case UnityWebRequest.Result.DataProcessingError:
                    Debug.LogError(pages[page] + ": Error: " + webRequest.error);
                    break;
                case UnityWebRequest.Result.ProtocolError:
                    Debug.LogError(pages[page] + ": HTTP Error: " + webRequest.error);
                    break;
                case UnityWebRequest.Result.Success:
                    Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
                    m_Token = webRequest.downloadHandler.text;
                    break;
            }
            yield break;
        // }
    }

The GetToken coroutine should wait for the UnityWebRequest to end and set the token variable before moving on to the next line and logging the value of the variable. It doesn't ... it happens immediately and then a short time later I get the response from the web request logged with the token. The CreateOrJoinRoom method is called prematurely.


Solution

  • StartCoroutine does not block code, so the lines in ConnectToLiveKit are being executed with normal order and timing.

    You can solve this by chaining together the routines like so:

    public void ConnectToLiveKit(string Username, string RoomName)
    {
        string query = $"?roomname={RoomName}&username={Username}";
        string fullUri = ServiceURL + query;
    
        StartCoroutine(ConnectRoutine(fullUri, Username, RoomName));
    }
    private IEnumerator ConnectRoutine(string uri, string username, string roomName)
    {
        yield return FetchTokenRoutine(uri);
    
        Debug.Log($"Token: {m_token}");
    
        // Handle no token here..
    
        yield return CreateOrJoinRoom(username, roomName);
    }
    private IEnumerator FetchTokenRoutine(string uri)
    {
        // Actual code here..
    }
    private IEnumerator CreateOrJoinRoom(string user, string roomName)
    {
        // Actual code here..
    }