2016-07-14 30 views
3

私は、Unityを使用してREST APIからデータを取り出して表示するHoloLensアプリケーションを作成しています。 私は現在、データを取得し、Update()関数から呼び出されるコルーチン内のreturn文を生成するためにWWWデータ型を使用しています。コードを実行しようとすると、APIから最新のデータが取得されますが、誰かが新しいデータをAPIにプッシュすると、リアルタイムで最新のデータが自動的に取得されません。最新のデータ。 マイコード:リソースキャッシュがサーバー上で有効になっているため、WWW/UnityWebRequest POST/GETリクエストでサーバー/ URLから最新のデータが返されない

using UnityEngine; 
using UnityEngine.UI; 
using System.Collections; 
using System; 
using Newtonsoft.Json; 
using System.Collections.Generic; 
using System.IO; 

public class TextChange : MonoBehaviour { 

    // Use this for initialization 
    WWW get; 
    public static string getreq; 
    Text text; 
    bool continueRequest = false; 

    void Start() 
    { 
     StartCoroutine(WaitForRequest()); 
     text = GetComponent<Text>(); 
    } 

    // Update is called once per frame 
    void Update() 
    { 

    } 

    private IEnumerator WaitForRequest() 
    { 
     if (continueRequest) 
      yield break; 

     continueRequest = true; 

     float requestFrequencyInSec = 5f; //Update after every 5 seconds 
     WaitForSeconds waitTime = new WaitForSeconds(requestFrequencyInSec); 

     while (continueRequest) 
     { 
      string url = "API Link goes Here"; 
      WWW get = new WWW(url); 
      yield return get; 
      getreq = get.text; 
      //check for errors 
      if (get.error == null) 
      { 
       string json = @getreq; 
       List<MyJSC> data = JsonConvert.DeserializeObject<List<MyJSC>>(json); 
       int l = data.Count; 
       text.text = "Data: " + data[l - 1].content; 
      } 
      else 
      { 
       Debug.Log("Error!-> " + get.error); 
      } 

      yield return waitTime; //Wait for requestFrequencyInSec time 
     } 
    } 

    void stopRequest() 
    { 
     continueRequest = false; 
    } 
} 

public class MyJSC 
{ 
    public string _id; 
    public string author; 
    public string content; 
    public string _v; 
    public string date; 
} 
+0

、あなたの質問に行ったようにあなたは、Update関数でコルーチン関数を呼び出すべきではありません。それは1秒で60以上のリクエストを作成するようなものです。私はあなたの質問でそれを待ってから再度要求を行うコードに置き換えることで対処しました。それがあなたの問題を解決しないなら、私の答えを見てください。 – Programmer

+0

解決方法を試しましたか? – Programmer

+1

はい、それは魅力的に機能しました.... –

答えて

5

これが起こっています。

3つの可能な解決策は、私は約知っています。 Disableサーバーにキャッシュするリソース。 InstructionsはすべてのWebサーバーで異なります。通常.htaccessで行われます。

。各リクエストを一意のタイムスタンプで作成します。時間はUnix形式でなければなりません。

この方法は、iOSでは機能しません。これはHoloLensのため、あなたは問題ありません。

たとえば、URLがhttp://url.com/file.rarの場合、末尾に?t=currentTimeを追加します。 currentTimeUnix形式の実際の時刻です。

完全なURL例:http://url.com/file.rar?t=1468475141

コード

string getUTCTime() 
{ 
    System.Int32 unixTimestamp = (System.Int32)(System.DateTime.UtcNow.Subtract(new System.DateTime(1970, 1, 1))).TotalSeconds; 
    return unixTimestamp.ToString(); 
} 

private IEnumerator WaitForRequest() 
{ 
    string url = "API Link goes Here" + "?t=" + getUTCTime(); 
    WWW get = new WWW(url); 
    yield return get; 
    getreq = get.text; 
    //check for errors 
    if (get.error == null) 
    { 
     string json = @getreq; 
     List<MyJSC> data = JsonConvert.DeserializeObject<List<MyJSC>>(json); 
     int l = data.Count; 
     text.text = "Data: " + data[l - 1].content; 
    } 
    else 
    { 
     Debug.Log("Error!-> " + get.error); 
    } 
} 

Disableキャッシュクライアント側のリクエストで、Cache-ControlPragmaヘッダーを指定して変更します。 max-age=0, no-cache, no-store

セットCache-Controlヘッダは次にno-cachePragmaヘッダを設定します。

WWWクラスの代わりにUnityWebRequestとすることをお勧めします。まず、using UnityEngine.Networking;を含めます。

コード

IEnumerator WaitForRequest(string url) 
{ 

    UnityWebRequest www = UnityWebRequest.Get(url); 
    www.SetRequestHeader("Cache-Control", "max-age=0, no-cache, no-store"); 
    www.SetRequestHeader("Pragma", "no-cache"); 

    yield return www.Send(); 
    if (www.isError) 
    { 
     Debug.Log(www.error); 
    } 
    else 
    { 
     Debug.Log("Received " + www.downloadHandler.text); 
    } 
} 
+0

補足として、更新の呼び出しにも対処する必要があります。現時点では、フレームごとに数十のコルーチンが起動しています。 InvokeRepeatingがより適切です。 – Everts

+0

@Evertsちょうどそれに気づいて、あなたは正しいです。私の答えはすでに長く、私はそれを長くしたくありません。私はそれを修正するために彼の答えを修正し、彼にそのことを知らせるために彼の質問の下でコメントしました。コルーチンですべてのタイプのUnity 'Invoke'関数を使うことはできません。 'while'ループはこれにふさわしいようです。彼の質問の更新されたコードをチェックして、私の言いたいことを見てください。 – Programmer

+0

コルーチンを開始するvoidメソッドを作成し、InvokeRepeatingを使用できます。 – Everts

関連する問題