【问题标题】:Iterating over multiple UnityWebRequests迭代多个 UnityWebRequest
【发布时间】:2019-11-21 10:21:05
【问题描述】:

我一直在尝试让一些 API 通信正常工作。我正在使用 UnityWebRequests,因为我想构建为 WebGL(我尝试了 System.Net.WebRequest,它在游戏模式下工作,但与 WebGL 不兼容)。这可能只是协程的问题,但我将以半伪的形式向您展示我到目前为止所拥有的以及我的问题是什么:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Collections.Generic;

public class scking : MonoBehaviour
{

    string tempText;
    string getUri = "https://api.opensensors.com/getProjectMessages";
    string jwtToken = "someToken";

    private void Start()
    {
        pullAllData();
    }

    IEnumerator GetDataRequest(string currentDateString, string nextDateString, string sensorID)
    {
        string requestParam = "myparameters: " + nextDateString + sensorID; // simplified dummy parameters

        using (UnityWebRequest webRequest = UnityWebRequest.Get(requestParam))
        {
            webRequest.SetRequestHeader("Authorization", "Bearer " + jwtToken);
            webRequest.SetRequestHeader("Content-Type", "application/json");

            yield return webRequest.SendWebRequest();

            // from unity api example
            string[] pages = getUri.Split('/');
            int page = pages.Length - 1;

            if (webRequest.isNetworkError)
            {
                Debug.Log(pages[page] + ": Error: " + webRequest.error);
            }
            else
            {
                Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
            }

            // getting the data i pulled out of the coroutine for further manipulation
            this.tempText = webRequest.downloadHandler.text;

            // show whats been pulled
            print(this.tempText);
        }
    }

    void pullAllData()
    {
        int allDaysCount = 10;
        List<int> sensorIds; // initialized with some ids

        for(int i = 0; i < allDaysCount - 1; i++)
        {
            for(int j = 0; j < sensorIds.Count; j++)
            {
                StartCoroutine(GetDataRequest(i, i + 1, sensorIds[j]));

                // show whats been pulled
                print(this.tempText);

                // parse json string this.tempText etc.
            }
        }

    }
}

输出是(按时间排序)

来自 pullAddData:null 中的打印

然后在协程中从 print 中下一步:jsonItem

基本上,协程花费的时间太长而且太晚了,我的循环无法继续,而且因为我得到一个空值,我当然无法解析或操作我的数据。或者也许我的整个工作都有缺陷,在那种情况下,如何正确地做到这一点?

非常感谢您对此提供的任何帮助。善良的菲利普

【问题讨论】:

  • 您需要在获得结果后打印结果,而不是假设它相当 instamatic
  • StartCoroutine 只会启动伪线程并立即返回。因此,如果您仅在开始请求后尝试在下一行中打印请求的结果,它将永远不会收到结果。数据的解析和操作必须发生在GetDataRequest 中,在yield 语句之后。这是您可以确定已收到服务器响应的地方。
  • 你的意思是这样的:Wait for all requests to continue(parallel) ?
  • 谢谢@BenjaminZach 好主意。正如你所说,它实际上运作良好。我仍然觉得必须有一个更迷人的解决方案。
  • @derHugo 这太棒了!我想在我的脑海中我想逐步完成每个请求,等待数据进来,处理它,将它存储在某个列表中,然后继续下一个 UnityWebRequest。

标签: c# api unity3d webrequest unitywebrequest


【解决方案1】:

如果你想等他们并行查看我对Wait for all requests to continue的回答


如果您还想一个接一个地等待它们,您可以简单地将它们包装成一个更大的协程:

void pullAllData()
{
    int allDaysCount = 10;
    List<int> sensorIds; // initialized with some ids

    // start the "parent" Coroutine
    StartCoroutine(GetAllData(allDaysCount, sensorIds));
}

IEnumerator GetAllData(int allDaysCount, List<int> sensorIds)
{
    for(int i = 0; i < allDaysCount - 1; i++)
    {
        for(int j = 0; j < sensorIds.Count; j++)
        {
            // Simply run and wait for this IEnumerator
            // in order to execute them one at a time
            yield return GetDataRequest(i, i + 1, sensorIds[j]);

            // show whats been pulled
            print(this.tempText);

            // parse json string this.tempText etc.
        }
    }

    // Maybe do something when all requests are finished and handled
}

IEnumerator GetDataRequest(string currentDateString, string nextDateString, string sensorID)
{
    string requestParam = "myparameters: " + nextDateString + sensorID; // simplified dummy parameters

    using (UnityWebRequest webRequest = UnityWebRequest.Get(requestParam))
    {
        webRequest.SetRequestHeader("Authorization", "Bearer " + jwtToken);
        webRequest.SetRequestHeader("Content-Type", "application/json");

        yield return webRequest.SendWebRequest();

        // from unity api example
        string[] pages = getUri.Split('/');
        int page = pages.Length - 1;

        if (webRequest.isNetworkError)
        {
            Debug.Log(pages[page] + ": Error: " + webRequest.error);
        }
        else
        {
            Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
        }

        // getting the data i pulled out of the coroutine for further manipulation
        this.tempText = webRequest.downloadHandler.text;

        // show whats been pulled
        print(this.tempText);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-13
    • 2019-05-05
    • 2013-02-14
    • 2021-05-05
    • 2010-09-27
    • 2017-01-01
    • 2020-10-21
    • 2015-08-23
    相关资源
    最近更新 更多