向Unity中的服务器发出GET请求的最佳方法

时间:2017-02-09 18:52:30

标签: c# json http unity3d httpwebrequest

现在我正在向服务器发出HTTP请求,但我还需要发送带有一些JSON数据的GET请求。我现在正在做的“工作”,但是很糟糕,因为它每次请求都下降到接近15 FPS。这是我的代码。

这是我的GET查询:

{
"query": {
    "match_all": {}
},
"size": 1,
"sort": [{
    "@timestamp": {
        "order": "desc"
    }
}]
}

这是我的开始方法:

void Start()
{
        queryString = File.ReadAllText(Application.streamingAssetsPath +"/gimmeData.json");

        StartCoroutine(SetJsonData()); 
}

以下是我为实际提出请求而设置的合作伙伴:

private IEnumerator SetJsonData()
{
    // Make a new web request with the .net WebRequest
    request = WebRequest.Create(elk_url);
    yield return null;

    request.ContentType = "application/json";
    request.Method = "POST";
    buffer = Encoding.GetEncoding("UTF-8").GetBytes(queryString);

    // Put this yield here so that I get higher FPS
    yield return null;

    requestStream = request.GetRequestStream();
    requestStream.Write(buffer, 0, buffer.Length);
    requestStream.Close();
    // Again this is about getting higher FPS
    yield return null;

    response = (HttpWebResponse)request.GetResponse();
    // Wait until we have all of the data we need from the response to continue
    yield return requestStream = response.GetResponseStream();

    // Open the stream using a StreamReader for easy access.
    reader = new StreamReader(requestStream);
    // Set my string to the response from the website
    JSON_String = reader.ReadToEnd();

    yield return null;

    // Cleanup the streams and the response.
    reader.Close();
    requestStream.Close();
    response.Close();
    yield return null;

    // As long as we are not null, put this in as real C# data
    if (JSON_String != null)
    {
        // Wait until we finish converting the string to JSON data to continue
        yield return StartCoroutine(StringToJson());  
    }

    if(dataObject != null)
    {
        // Send the data to the game controller for all of our hits
        for(int i = 0; i < dataObject.hits.hits.Length; i++)
        {
            StartCoroutine(
                gameControllerObj.CheckIpEnum(dataObject.hits.hits[i]._source));
        }
    }

    // As long as we didn't say to stop yet
    if (keepGoing)
    {
        yield return null;

        // Start this again
        StartCoroutine(SetJsonData());
    }
}

我拥有所有那些“yield return null”,因为它改进了现有的FPS。

如何优化此功能?有没有更好的方法来制作一个Web请求,也可以用它发送GET数据?我知道UnityWebRequest是一个东西,但这不允许我发送我拥有的JSON数据。

1 个答案:

答案 0 :(得分:2)

注意:问题中的代码是执行POST,而不是GET。没有“获取数据”这样的东西。

以下建议等同于服务器的观点

如果您确实需要GET请求 - 即与您的代码完全不同的内容 - 请参阅此答案的结尾。

协同程序不是线程

Wait until we have all of the data - 这就是你的帧率降临的地方。这是因为Unity主线程 - 基本上是整个游戏 - 将等待服务器响应所有数据。

简而言之,这只是因为协同程序的工作方式 - 它们与线程非常不同。

Unity中的一般方法是在协程中使用WWW。内部Unity在一个单独的线程上运行实际请求,而协程只是经常检查进度:

发布,匹配您的问题代码:

// Build up the headers:
Dictionary<string,string> headers = new Dictionary<string,string>();

// Add in content type:
headers["Content-Type"] = "application/json";

// Get the post data:
byte[] postData = Encoding.GetEncoding("UTF-8").GetBytes(queryString);

// Start up the reqest:
WWW myRequest = new WWW(elk_url, postData, headers);

// Yield until it's done:
yield return myRequest;

// Get the response (into your JSON_String field like above)
// Don't forget to also check myRequest.error too.
JSON_String = myRequest.text;

// Load the JSON as an object and do magical things next.
// There's no need to add extra yields because
// your JSON parser probably doesn't support chunked json anyway.        
// They can cover a few hundred kb of JSON in an unnoticeable amount of time.
....

GET,匹配您的问题:

// Start up the reqest (Total guess based on your variable names):
// E.g. mysite.com/hello?id=2&test=hi
WWW myRequest = new WWW(elk_url + "?"+queryString);

// Yield until it's done:
yield return myRequest;

// Get the response
JSON_String = myRequest.text;
....