A method for making HTTP requests on Unity iOS?

前端 未结 4 478
北荒
北荒 2020-12-04 22:33

I need to send HTTP requests with all the standard RESTful methods and access to the body of the request in order to send/receive JSON with it. I\'ve looked into,

W

4条回答
  •  广开言路
    2020-12-04 23:13

    Ok, I finally managed to write my own solution. We basically need a RequestState, a Callback Method and a TimeOut Thread. Here I'll just copy what was done in UnifyCommunity (now called unity3d wiki). This is outdated code, but smaller than what's there, so more convenient to show something here. Now I've removed (in the unit3d wiki) System.Action and static for performance and simplicity:

    Usage

    static public ThisClass Instance;
    void Awake () {
        Instance = GetComponent();
    }
    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;
    
    /// 
    ///  The RequestState class passes data across async calls.
    /// 
    public class RequestState
    {
        public WebRequest webRequest;
        public string errorMessage;
    
        public RequestState ()
        {
            webRequest = null;
            errorMessage = null;
        }
    }
    
    public class WebAsync {
        const int TIMEOUT = 10; // seconds
    
        /// 
        /// If the URLs returns 404 or connection is broken, it's missing. Else, we suppose it's fine.
        /// 
        /// 
        /// A fully formated URL.
        /// 
        /// 
        /// 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
        /// 
        static public IEnumerator CheckForMissingURL (string url, System.Action 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);
            }
        }
    }
    

提交回复
热议问题