在Unity iOS上创buildHTTP请求的方法?

我需要使用所有标准的RESTful方法发送HTTP请求,并访问请求的主体以便发送/接收JSON。 我看过,

WebRequest.HttpWebRequest

这几乎是完美的,但是有些情况下,例如,如果服务器closures,GetResponse函数可能需要几秒钟的时间才能返回 – 因为它是一个同步方法 – 冻结该时期的应用程序。 BeginGetResponse这个方法的asynchronous版本似乎并不是asynchronous工作的(在Unity中),因为它仍然冻结了那个时期的应用程序。

UnityEngine.WWW#

由于某种原因,只支持POST和GET请求 – 但是我也需要PUT和DELETE(标准的RESTful方法),所以我没有更进一步的研究它。

的System.Threading

为了运行WebRequest.HttpWebRequest.GetResponse而不冻结我使用线程查看的应用程序。 线程似乎在编辑器中工作(但看起来非常不稳定 – 如果在应用程序退出时不停止线程,即使在停止时仍然在编辑器中运行),并且当iOS设备内置时因为我尝试启动一个线程(我忘了写下错误,现在我无法访问它)。

在本地iOS应用程序中运行线程,并使用桥接到Unity应用程序

可笑,甚至不会去尝试这个。

UniWeb

这个。 我想知道他们是如何pipe理的。

下面是我正在尝试的WebRequest.BeginGetResponse方法的示例,

// The RequestState class passes data across async calls. public class RequestState { const int BufferSize = 1024; public StringBuilder RequestData; public byte[] BufferRead; public WebRequest Request; public Stream ResponseStream; // Create Decoder for appropriate enconding type. public Decoder StreamDecode = Encoding.UTF8.GetDecoder(); public RequestState() { BufferRead = new byte[BufferSize]; RequestData = new StringBuilder(String.Empty); Request = null; ResponseStream = null; } } public class WebRequester { private void ExecuteRequest() { RequestState requestState = new RequestState(); WebRequest request = WebRequest.Create("mysite"); request.BeginGetResponse(new AsyncCallback(Callback), requestState); } private void Callback(IAsyncResult ar) { // Get the RequestState object from the async result. RequestState rs = (RequestState) ar.AsyncState; // Get the WebRequest from RequestState. WebRequest req = rs.Request; // Call EndGetResponse, which produces the WebResponse object // that came from the request issued above. WebResponse resp = req.EndGetResponse(ar); } } 

…基于此: http : //msdn.microsoft.com/en-us/library/86wf6409(v=vs.71).aspx

好吧,我终于设法写我自己的解决scheme 。 我们基本上需要一个RequestState ,一个callback方法和一个TimeOut线程 。 在这里,我将复制在UnifyCommunity (现在称为unity3d wiki)中完成的工作。 这是过时的代码,但比在那里小,所以在这里显示更方便。 现在我已经移除(在unit3d维基) System.Actionstatic性能和简单性:

用法

 static public ThisClass Instance; void Awake () { Instance = GetComponent<ThisClass>(); } static private IEnumerator CheckAvailabilityNow () { bool foundURL; string checkThisURL = "http://www.example.com/index.html"; yield return Instance.StartCoroutine( WebAsync.CheckForMissingURL(checkThisURL, value => foundURL = !value) ); Debug.Log("Does "+ checkThisURL +" exist? "+ foundURL); } 

WebAsync.cs

 using System; using System.IO; using System.Net; using System.Threading; using System.Collections; using UnityEngine; /// <summary> /// The RequestState class passes data across async calls. /// </summary> public class RequestState { public WebRequest webRequest; public string errorMessage; public RequestState () { webRequest = null; errorMessage = null; } } public class WebAsync { const int TIMEOUT = 10; // seconds /// <summary> /// If the URLs returns 404 or connection is broken, it's missing. Else, we suppose it's fine. /// </summary> /// <param name='url'> /// A fully formated URL. /// </param> /// <param name='result'> /// This will bring 'true' if 404 or connection broken and 'false' for everything else. /// Use it as this, where "value" is a System sintaxe: /// value => your-bool-var = value /// </param> static public IEnumerator CheckForMissingURL (string url, System.Action<bool> result) { result(false); Uri httpSite = new Uri(url); WebRequest webRequest = WebRequest.Create(httpSite); // We need no more than HTTP's head webRequest.Method = "HEAD"; RequestState requestState = new RequestState(); // Put the request into the state object so it can be passed around requestState.webRequest = webRequest; // Do the actual async call here IAsyncResult asyncResult = (IAsyncResult) webRequest.BeginGetResponse( new AsyncCallback(RespCallback), requestState); // WebRequest timeout won't work in async calls, so we need this instead ThreadPool.RegisterWaitForSingleObject( asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), requestState, (TIMEOUT *1000), // obviously because this is in miliseconds true ); // Wait until the the call is completed while (!asyncResult.IsCompleted) { yield return null; } // Deal up with the results if (requestState.errorMessage != null) { if ( requestState.errorMessage.Contains("404") || requestState.errorMessage.Contains("NameResolutionFailure") ) { result(true); } else { Debug.LogWarning("[WebAsync] Error trying to verify if URL '"+ url +"' exists: "+ requestState.errorMessage); } } } static private void RespCallback (IAsyncResult asyncResult) { RequestState requestState = (RequestState) asyncResult.AsyncState; WebRequest webRequest = requestState.webRequest; try { webRequest.EndGetResponse(asyncResult); } catch (WebException webException) { requestState.errorMessage = webException.Message; } } static private void ScanTimeoutCallback (object state, bool timedOut) { if (timedOut) { RequestState requestState = (RequestState)state; if (requestState != null) requestState.webRequest.Abort(); } else { RegisteredWaitHandle registeredWaitHandle = (RegisteredWaitHandle)state; if (registeredWaitHandle != null) registeredWaitHandle.Unregister(null); } } } 

我有线程在iOS上工作,我相信它是由于线程或者其他原因而崩溃的。 重新启动设备似乎已经修复了崩溃,所以我将使用WebRequest.HttpWebRequest与线程。

有一种方法是asynchronous执行此操作,而不使用IEnumerator并产生返回的东西。 查看eDriven框架。

HttpConnector类: https : //github.com/dkozar/eDriven/blob/master/eDriven.Networking/Rpc/Core/HttpConnector.cs

我一直在使用JsonFX和HttpConnector,例如在这个WebPlayer演示中: http ://edrivenunity.com/load-images

没有PUT和DELETE不是一个大问题,因为所有这些都可以使用GET和POST来完成。 例如,我正在使用其REST服务成功地与Drupal CMS进行通信。

 // javascript in the web player not ios, android or desktop you could just run the following code: var jscall:String; jscall="var reqScript = document.createElement('script');"; jscall+="reqScript.src = 'synchmanager_secure2.jsp?userid="+uid+"&token="+access_token+"&rnd='+Math.random()*777;"; jscall+="document.body.appendChild(reqScript);"; Application.ExternalEval(jscall); // cs string jscall; jscall="var reqScript = document.createElement('script');"; jscall+="reqScript.src = 'synchmanager_secure2.jsp?userid="+uid+"&token="+access_token+"&rnd='+Math.random()*777;"; jscall+="document.body.appendChild(reqScript);"; Application.ExternalEval(jscall); // then update your object using the your return in a function like this // json return object always asynch function sendMyReturn(args){ var unity=getUnity(); unity.SendMessage("object", "function", args ); } sendMyReturn(args); 

或者你可以通过一个AJAX函数发送它为了安全的目的预先定制的头,你需要签名的头和从服务器返回一个签名的请求我更喜欢md5签名比较他们不是那么大