Unity GET/POST Wrapper

匿名 (未验证) 提交于 2019-12-03 01:41:02

问题:

This is a Unity3d in C# question. The goal is to create an object such that I can pass in a URL and receive data via GET, an object that I would create the would be a wrapper for the WWW logic. I would also like a 'POST' object too, where I could supply a url and a 'Dictionary' of key-value pairs as the post arguements. Sooo... we ultimately would like something like this:

get_data = GET.request("http://www.someurl.com/somefile.php?somevariable=somevalue"); 

AND

post_data = POST.request("http://www.someurl.com/somefile.php", post) // Where post is a Dictionary of key-value pairs of my post arguments.  

To try and accomplish this, I use the WWW object. Now, in order to give the WWW object time to download, we need to have this happening inside a MonoBehaviour object and yield the results. So I got this, which works:

public class main : MonoBehavior {     IEnumerator Start()     {         WWW www = new WWW("http://www.someurl.com/blah.php?action=awesome_stuff");          yield return www;         Debug.Log(www.text);     } } 

What I really want is this:

public class main : MonoBehavior {     IEnumerator Start()     {         GET request = new GET("http://www.someurl.com/blah.php?action=awesome_stuff");          Debug.Log(request.get_data()); // Where get_data() returns the data (which will be text) from the request.        } } 

Now I have the main script attached to the single GameObject in the hierarchy (called root). Do I need to have the GET script attached to the root GameObject as well? Can I do that dynamically from main?

Ultimately, I need a solution that allows me to easily send GET and POST requests.

Cheers!

回答1:

Ah, Got it!

My problem was a misunderstanding of how MonoBehaviour and Coroutines worked. The solution is very simple.

In the editor, make an empty GameObject. I named it DB. Then attach the following script to it:

using System; using UnityEngine; using System.Collections; using System.Collections.Generic; class DB : MonoBehaviour {     void Start() { }      public WWW GET(string url)     {         WWW www = new WWW(url);         StartCoroutine(WaitForRequest(www));         return www;     }      public WWW POST(string url, Dictionary post)     {         WWWForm form = new WWWForm();         foreach (KeyValuePair post_arg in post)         {             form.AddField(post_arg.Key, post_arg.Value);         }         WWW www = new WWW(url, form);          StartCoroutine(WaitForRequest(www));         return www;     }      private IEnumerator WaitForRequest(WWW www)     {         yield return www;          // check for errors         if (www.error == null)         {             Debug.Log("WWW Ok!: " + www.text);         }         else         {             Debug.Log("WWW Error: " + www.error);         }     } } 

Then, in your main script's start function, you can do this!

private DB db; void Start() {     db = GameObject.Find("DB").GetComponentInChildren();     results = db.GET("http://www.somesite.com/someAPI.php?someaction=AWESOME");     Debug.Log(results.text); } 

Haven't tested the POST requests, but now all the logic is wrapped up! Send HTTP requests to your hearts desire, cheers!



回答2:

What is that GET script that you're referring to? The WWW class allows you to retrieve GET data just fine, the information you need is in the text property of the instantiated WWW object. Here's the documentation:

http://unity3d.com/support/documentation/ScriptReference/WWW-text.html http://unity3d.com/support/documentation/ScriptReference/WWW.html

All you need to do is yield the WWW object, as you're doing just now, and then read any of the properties you're interested in, plain and simple, no extra classes needed.

As for sending a POST object, that's what the WWWForm class is for:

http://unity3d.com/support/documentation/ScriptReference/WWWForm.html

In short, you just create a WWWForm object, add fields to it through AddField(), and then simply construct a new WWW object with the POST URL & the former object, that's it. Yield the WWW object and once it comes back you're data has been submitted. Responses are, again, in the text property & errors in the corresponding field. Plain, clean & simple.

HTH!



回答3:

Here is @pandemoniumsyndicate's code modified to add a callback. The original code is not completely correct, since the GET and POST functions will exit immediately after calling the coroutine. At that time it is likely that the WWW request is not yet complete and accessing any field except (www.isDone) is pointless.

The following code defines a delegate, WWWRequestFinished, which will be called when the request is finished with the result of the request and data received, if any.

using System; using UnityEngine; using System.Collections; using System.Collections.Generic;  public class WWWRequestor : MonoBehaviour  {      Dictionary mRequestData = new Dictionary();     public delegate void WWWRequestFinished(string pSuccess, string pData);      void Start() { }      public WWW GET(string url, WWWRequestFinished pDelegate)     {         WWW aWww = new WWW(url);         mRequestData[aWww] = pDelegate;          StartCoroutine(WaitForRequest(aWww));         return aWww;     }      public WWW POST(string url, Dictionary post, WWWRequestFinished pDelegate)     {         WWWForm aForm = new WWWForm();         foreach (KeyValuePair post_arg in post)         {             aForm.AddField(post_arg.Key, post_arg.Value);         }         WWW aWww = new WWW(url, aForm);          mRequestData[aWww] = pDelegate;         StartCoroutine(WaitForRequest(aWww));         return aWww;     }      private IEnumerator WaitForRequest(WWW pWww)     {         yield return pWww;          // check for errors         string aSuccess = "success";         if (pWww.error != null)         {             aSuccess = pWww.error;         }          WWWRequestFinished aDelegate = (WWWRequestFinished) mRequestData[pWww];         aDelegate(aSuccess, pWww.text);         mRequestData.Remove(pWww);     }  } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!