使用Unity的HTTP客户端,应用程序挂起

时间:2017-10-24 04:29:33

标签: c# http

我的Unity游戏中有一个非常基本的脚本,它试图将POST中的表单数据提交给服务器。但团结似乎无限期地冻结/悬挂。我很困惑为什么会这样,所以我不知道如何解决这个问题。

我在本文后面松散地制作了我的代码: https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient#making-web-requests

我的服务器确实收到了请求并写回了一个。但是因为团结被冻结了,目前还没有真正可用。

我的班级看起来像这样:

public class HTTPManager : MonoBehaviour
{
    private static HttpClient client = new HttpClient();
    private void Awake()
    {
        client.BaseAddress = new Uri("http://localhost:8080/");
        ProcessRepositories().Wait();
    }

    private async Task ProcessRepositories()
    {
        client.DefaultRequestHeaders.Accept.Clear();

        FormUrlEncodedContent content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("u", "test")
        });

        //this goes to http://localhost:8080/hello with POST u=test
        HttpResponseMessage result = await client.PostAsync("hello",content);

        Debug.Log("Is Success: "+result.IsSuccessStatusCode);
        Debug.Log("Status code: "+result.StatusCode);
        Debug.Log("Reason Phrase: "+result.ReasonPhrase);
        Debug.Log("Headers: "+result.Headers);
        Debug.Log("Content: "+result.Content);
        Debug.Log("Request Message: "+result.RequestMessage);
        Debug.Log("Version: "+result.Version);

    }
}

导致悬挂问题的原因是什么?

2 个答案:

答案 0 :(得分:3)

ProcessRepositories().Wait();

阻止了async代码并导致死锁。 Stephen Clearly在this上发布了一系列帖子。

将所有代码async全部提升或安排Task上的延续。

编辑:似乎AwakeUnity方法。为此,您有4个选项:

1)从async Task移除ProcessRepositories()。删除方法正文中的await并使您对服务器的调用同步。这会导致抖动,而不是游戏环境中推荐的解决方案。

2)从.Wait()移除ProcessRepositories()。这将导致您的代码异步发布到服务器,但您将无法对响应执行任何操作。如果您不关心响应,这很好。

3。)如果你关心回复,可以在Continuations上安排ProcessRepositories()。这是一种“回调”,会在TaskRanToCompletion或出错时运行。要实现此目的,请将ProcessRepositories()更改为ProcessRepositories().ContinueWith(task=> { // in here you can access task.Result to get your response })并更改ProcessRepositories方法以返回HttpResponseMessage resultreturn await client.PostAsync("hello",content);

4)如下所述使用ConfigureAwait(false),但是会在不同的上下文中返回结果并看到这个Unity,你可能想要在UI线程上得到结果,所以请注意这一点。

答案 1 :(得分:0)

不要将HttpClient与团结一起使用,使用类WWW和内置协同程序功能的单元,返回它并等待下载完成。

public class HTTPManager : MonoBehaviour
{
    private IEnumerator Awake()
    {
        return ProcessRepositories();
    }

    private IEnumerator ProcessRepositories()
    {
        var form = new WWWForm();
        form.AddField("u", "test");
        var www = new WWW("http://localhost:8080/hello", form);
        yield return www;

        Debug.Log("responseHeaders: "+www.responseHeaders);
        Debug.Log("text: "+www.text);
    }
}