2016-07-14 28 views
3

Ich erstelle eine HoloLens App mit Unity, die Daten aus einer REST API nehmen und anzeigen muss. Ich verwende derzeit den WWW-Datentyp, um die Rückgabeanweisung für Daten und Yield in einer Coroutine abzurufen, die von der Funktion Update() aufgerufen wird. Wenn ich versuche, den Code auszuführen, erhalte ich die neuesten Daten von der API, aber wenn jemand neue Daten auf die API drückt, erhält er nicht automatisch die neuesten Daten in Echtzeit und ich muss die App neu starten, um die zu sehen neueste Daten. Mein Code:WWW/UnityWebRequest POST/GET Anfrage wird nicht die neuesten Daten von Server/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

Sie sollten keine Koroutine Funktion in der Update-Funktion anrufen, wie Sie in Ihrer Frage haben. Das ist, als ob man 60+ Anfragen in einer Sekunde erledigt. Ich habe das in Ihrer Frage angesprochen, indem Sie es durch einen Code ersetzen, der wartet und dann erneut eine Anfrage macht. Wenn das Ihr Problem nicht löst, sehen Sie meine Antwort. – Programmer

+0

Haben Sie die Lösung versucht? – Programmer

+1

Ja, und es hat wie ein Charme funktioniert .... –

Antwort

5

Dies geschieht, weil Ressourcen-Caching auf dem Server aktiviert ist.

Drei mögliche Lösungen Ich weiß über:

. Disable Ressourcen im Cache auf Server. Instructions sind für jeden Webserver unterschiedlich. Normalerweise erfolgt dies in .htaccess.

.Machen Sie jede Anfrage mit einem eindeutigen Zeitstempel. Die Uhrzeit sollte in Unix formatieren.

Diese Methode funktioniert nicht unter iOS. Es geht Ihnen gut, da dies für HoloLens ist. Wenn Ihre URL http://url.com/file.rar lautet, fügen Sie am Ende ?t=currentTime an. currentTime ist die tatsächliche Zeit in Unix Format.

Voll Beispiel url: http://url.com/file.rar?t=1468475141

-Code:

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 auf Client Seite durch die Lieferung und Änderung der Cache-Control und Pragma Header in der Anfrage.

Set Cache-ControlKopf-max-age=0, no-cache, no-store stellen Sie dann PragmaKopf-no-cache.

Ich schlage vor, Sie tun dies mit UnityWebRequest anstelle der WWW Klasse. Enthalten Sie zuerst using UnityEngine.Networking;.

-Code:

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

Als Randnotiz sollten Sie auch den Anruf in Update ansprechen. Im Moment sind Dutzende von Coroutinen pro Frame gestartet. InvokeRepeating ist besser geeignet. – Everts

+0

@Everts Gerade bemerkt, dass und Sie haben Recht. Meine Antwort ist schon lang und ich will es nicht länger machen. Ich habe seine Antwort geändert, um das zu beheben, und unter seiner Frage kommentiert, um ihn darüber zu informieren. Beachten Sie, dass Sie nicht alle Arten von Unity 'Invoke'-Funktionen mit Coroutinen verwenden können. 'while' Schleife scheint dafür geeignet zu sein. Überprüfen Sie den aktualisierten Code in seiner Frage, um zu sehen, was ich meine. – Programmer

+0

Machen Sie eine Void-Methode, die die Coroutine startet, dann können Sie InvokeRepeating verwenden. – Everts