使用 C# 从 Unity 中的 REST Api 无延迟或抖动地检索数据

Posted

技术标签:

【中文标题】使用 C# 从 Unity 中的 REST Api 无延迟或抖动地检索数据【英文标题】:Retrieving data from REST Api in Unity without lag or jitter using C# 【发布时间】:2016-12-26 04:16:17 【问题描述】:

每 5 秒我使用 C# 脚本调用 REST。但问题是应用程序每 10 秒滞后一次(InvokeRepeating)并等待服务器响应,然后在滞后后给出结果。

如何解决这个问题??我需要实时访问特定的行,以便在没有任何延迟的情况下检索更改。

以下代码-sn-p用于读取REST Api

using UnityEngine;
using System.Collections;
using System.Net;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;


public class Rows 

public string description ;
public float Efficiency;
public bool IsConnected;
public string Lastconnection;
public float MTBF;
public float MTTR;
public string Name;
public float Speed;
public float TemperatureSetPoint;



public class GetData : MonoBehaviour 


string url="http:LocalHost/Data/Properties/";
string username="Administrator";
string password="admin";
string rt;


void Start () 
    JToken tok = CallWeb();



public JToken CallWeb()

     
        var httpRequest = (HttpWebRequest)WebRequest.Create (url);
        httpRequest.ContentType = "application/json";

        string encoded = System.Convert.ToBase64String (System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username+":"+password));
        httpRequest.Headers.Add ("Authorization","Basic "+encoded);
        httpRequest.Accept = "application/json";

        using (HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse())
        using (Stream stream = response.GetResponseStream())
        using (StreamReader reader = new StreamReader(stream))
        
            rt = reader.ReadToEnd();
            JObject data = JObject.Parse(rt);
            JToken token = (data["rows"][0]);
            return token;
               
        
    

从下面的代码中,我访问所需的行并统一使用它。

    using UnityEngine;
    using System.Collections;
    using Newtonsoft.Json.Linq;
    using UnityEngine.UI;

    public class GetPropertyValues : MonoBehaviour
    

        GetData thing = new GetData ();

        public GameObject CountText;
        public GameObject TempText;
        static string CountValue1;
        static string CountValue2;
        static string TempValue1;
        static string TempValue2;


        void Start()
        
            JToken token = thing.CallWeb ();
            foreach (JProperty prop in token) 
                       
                if (prop.Name == "ScrapCount") 
                 
                    CountValue1 = prop.Value.ToString ();
                    CountText.GetComponent<TextMesh> ().text = "Count= "+CountValue1.ToString() ;
                    Debug.Log ("This is the Count value" + prop.Value);
                    InvokeRepeating ("countDisplay", 5, 10);
                
                if (prop.Name == "OvenTemperature") 
                
                    TempValue1 = prop.Value.ToString ();
                    TempText.GetComponent<TextMesh> ().text = TempValue1.ToString () + "'C";
                    Debug.Log ("This is the Temp value" + prop.Value);
                    InvokeRepeating ("tempDisplay", 5, 10);

                
            
        

        void countDisplay()
        
            JToken token = thing.CallThingWorx ();
            foreach (JProperty prop in token) 
                if (prop.Name == "ScrapCount") 
                    CountValue2 = prop.Value.ToString ();
                    if (CountValue1 == CountValue2) 
                        Debug.Log ("count value is still " + CountValue1);
                    
                    else if (CountValue1 != CountValue2) 
                        CountText.GetComponent<TextMesh> ().text = "Count= " + CountValue2.ToString();
                        Debug.Log ("count value Changed" + CountValue2);
                    
                
            
        

        void tempDisplay()
        
            JToken token = thing.CallWeb ();
            foreach (JProperty prop in token) 
            
                if (prop.Name == "OvenTemperature") 
                
                    TempValue2 = prop.Value.ToString ();
                    if (TempValue1 == TempValue2) 
                    
                        Debug.Log ("Temp value is still " + TempValue1);
                    
                    else if (TempValue1 != TempValue2) 
                    
                        TempText.GetComponent<TextMesh> ().text = TempValue2.ToString() +"'C";
                        Debug.Log ("Temp value Changed" + TempValue2);
                    
                
            
        
    

【问题讨论】:

【参考方案1】:

您似乎正在执行同步请求。尝试使用 Unity 提供的功能

https://docs.unity3d.com/Manual/UnityWebRequest.html

class MyBehaviour: public MonoBehaviour 
    void Start() 
        StartCoroutine(GetText());
    

    IEnumerator GetText() 
        UnityWebRequest www = UnityWebRequest.Get("http://www.my-server.com");
        yield return www.Send();

        if(www.isError) 
            Debug.Log(www.error);
        
        else 
            // Show results as text
            Debug.Log(www.downloadHandler.text);

            // Or retrieve results as binary data
            byte[] results = www.downloadHandler.data;
        
    
    // Edit here
    StartCoroutine(GetText());

这将使您的应用在获取数据时保持运行。 else 语句是下载完成后您的操作所在。

【讨论】:

非常感谢 :) 我采纳了您的建议,只收到了 1 次回复。我应该怎么做才能使应用程序与 url 不断同步?这有助于检索不断更改的值??? 在其末尾启动同一个协程。 感谢您的支持。我试过这个,它只在 Unity 编辑器中工作得很好,但在构建它之后不能在 android 应用程序中工作。我们是否必须在清单中提供单独的权限才能在应用程序中完成这项工作?如果有,需要补充什么? 是的,需要互联网。 developer.android.com/training/basics/network-ops/… 是的,在那里 除了这个 ???

以上是关于使用 C# 从 Unity 中的 REST Api 无延迟或抖动地检索数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# REST API 从 TFS 获取用户身份

C# 转换中的 HttpURLConnection REST API

如何在 C# 中使用 rest api 从 github 为用户(人)获取数据?

需要帮助使用 PayPal REST API 或 C# 中的任何其他方法获取 PayPal 交易

使用 C# 将 REST API 数据自动转换为 csv

Rest API Post Json 使用带有两个参数的 C#