2017-10-24 5 views
2

私はUnityゲームで、フォームデータをPOSTでサーバーに送信しようとしているかなり基本的なスクリプトを持っています。しかし、団結は無期限にフリーズ/ハングするようです。私はなぜこれが起こっているのか混乱しているので、私は問題を解決する方法を知らない。 Unityを持つHTTPクライアント、アプリケーションがハング

は私が緩く、この記事で次のように私のコードを作っ: https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient#making-web-requests

私のサーバーが要求を受信ず、1人の背中を書きありません。しかし、統一が凍っているので、現時点では本当に使えません。

私のクラスには、次のようになります。

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); 

    } 
} 

をぶら下げ問題を引き起こしていただきました!?

+0

[WWW](https://docs.unity3d.com/ScriptReference/WWW.html)クラスを使用して、あなたはコルーチンでそれを使用することができ、歩留まりそれを返す、団結とのHttpClientを使用しないでください。また、ダウンロードが完了するのを待ちます。 –

+0

コルーチンと非同期のものは何ですか? – Sir

+0

https://forum.unity.com/threads/coroutine-vs-async-method.483746/ –

答えて

3
ProcessRepositories().Wait(); 

は、asyncコードでブロックされており、デッドロックが発生しています。スティーブンは明らかにthisに一連の記事を掲載しています。

asyncのコードをすべて作成するか、またはTaskで続行をスケジュールしてください。

編集:AwakeUnityの方法です。これには4つのオプションがあります:

1)ProcessRepositories()からasync Taskを削除します。方法本体のawaitを削除し、サーバーへの呼び出しを同期させます。これはジッタを引き起こし、ゲーム環境で推奨される解決策ではありません。

2)ProcessRepositories()から.Wait()を削除します。これにより、コードがサーバへのポストバックを非同期にすることになりますが、そのレスポンスでは何もできなくなります。あなたが応答を気にしないなら、これは問題ありません。

3)応答が気になる場合はContinuationsProcessRepositories()にスケジュールすることができます。これは、TaskRanToCompletionがあるか、エラーが発生したときに実行される「コールバック」の一種です。これを達成するために、ProcessRepositories().ContinueWith(task=> { // in here you can access task.Result to get your response })からProcessRepositories()を変更して返すために、あなたのProcessRepositories方法を変更HttpResponseMessageresult すなわちreturn await client.PostAsync("hello",content);

4)後述するようにConfigureAwait(false)を使用しますが、それは別のコンテキストに結果を返すと見て、このユニティこと、あなたはおそらくされますUIスレッド上で結果を欲しいので、それを気にしてください。

+0

ああああ、記事には.Wait()がありました。その後、私はそれを削除しました。それを持っていた。それはありがとう:)あなたはウェブサーバーから結果のテキストを取得する方法を知っている、私はresult.Contentそれをしたと思ったが、それは 'Content:System.Net.Httpを与えた。StreamContent'は正しくはありません。 – Sir

+0

あなたは 'await result.Content.ReadAsStringAsync()'を試すことができます – JohanP

+0

うーん、それはどこに行くのですか?私のPostAsyncとは別のものとして?編集:ああ作品:)ありがとう – Sir

0

HttpClientを1と組み合わせて使用​​しないでください。クラス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); 
    } 
} 
+0

問題は単体です。docsはHTTPS証明書の使用方法について何も言及していません。セットアップでサポートされていないと思われますか? – Sir

+0

クライアント証明書を使用していますか(つまり、答えが「いいえ」であることがわからない場合)、単にhttps://と入力していないと証明書が正常に機能していない場合。 –

+0

私の計画は、HTTPSでクライアント証明書を使用することです。ログイン/登録用。 – Sir

関連する問題