unity tag script prefab posicion obtener objeto from create c# ios multithreading http unity3d

c# - tag - unity static inspector



¿Un método para realizar solicitudes HTTP en Unity iOS? (4)

Hay una forma de hacerlo asincrónicamente, sin usar IEnumerator y rendimiento de retorno. Mira el marco eDriven.

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

He estado usando JsonFX con HttpConnector todo el tiempo, por ejemplo en esta demostración de WebPlayer: http://edrivenunity.com/load-images

No tener PUT y DELETE no es un gran problema, ya que todo se puede hacer usando GET y POST. Por ejemplo, estoy comunicándome con éxito con Drupal CMS usando su servicio REST.

Necesito enviar solicitudes HTTP con todos los métodos RESTful estándar y acceder al cuerpo de la solicitud para enviar / recibir JSON con ella. He investigado

WebRequest.HttpWebRequest

Esto funciona casi a la perfección, pero hay casos en que, por ejemplo, si el servidor está inactivo, la función GetResponse puede demorar varios segundos en regresar, ya que es un método síncrono, congelando la aplicación para ese período. La versión asíncrona de este método, BeginGetResponse, no parece funcionar de manera asincrónica (en Unity de todos modos) ya que todavía congela la aplicación para ese período.

UnityEngine.WWW #

Solo admite solicitudes POST y GET por alguna razón, pero también necesito PUT y DELETE (métodos RESTful estándar), así que no me molesté en buscar más.

System.Threading

Para ejecutar WebRequest.HttpWebRequest.GetResponse sin congelar la aplicación, analicé el uso de subprocesos. Los hilos parecen funcionar en el editor (pero parecen extremadamente volátiles; si no detiene un hilo cuando la aplicación sale, se ejecuta en el editor para siempre, incluso cuando lo detiene), y cuando se construye en un dispositivo iOS, lo cuelga tan pronto como sea posible. cuando trato de iniciar un hilo (olvidé escribir el error y no tengo acceso a él en este momento).

Ejecute subprocesos en una aplicación nativa de iOS con un puente a la aplicación Unity

Ridículo, ni siquiera voy a intentar esto.

UniWeb

Esta. Me gustaría saber cómo lo lograron.

Aquí hay un ejemplo del método WebRequest.BeginGetResponse que estoy intentando,

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

... basado en esto: http://msdn.microsoft.com/en-us/library/86wf6409(v=vs.71).aspx


Me puse a trabajar en iOS, creo que se estaba bloqueando debido a los hilos fantasma o algo así. Reiniciar el dispositivo parece haber solucionado el bloqueo, así que solo usaré WebRequest.HttpWebRequest con subprocesos.


Ok, finalmente logré escribir mi propia solución . Básicamente, necesitamos un RequestState , un Callback Method y un TimeOut Thread . Aquí solo copiaré lo que se hizo en UnifyCommunity (ahora llamado wiki de unity3d). Este es código obsoleto, pero más pequeño que lo que está allí, por lo que es más conveniente mostrar algo aquí. Ahora eliminé (en el wiki de unit3d) System.Action y static para rendimiento y simplicidad:

Uso

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


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

o puede enviarlo a través de una función AJAX encabezados personalizados preescritos para fines de seguridad, con esto necesitaría encabezados firmados y una solicitud firmada del servidor. Prefiero las firmas md5, comparativamente, no son tan grandes.