Unity GET / POST Wrapper - PullRequest
       18

Unity GET / POST Wrapper

17 голосов
/ 21 января 2012

Это вопрос Unity3d в C #.Цель состоит в том, чтобы создать объект таким образом, чтобы я мог передавать URL-адрес и получать данные через GET, объект, который я бы создал, был бы оболочкой для логики WWW.Я также хотел бы также объект 'POST', где я мог бы предоставить url и 'Dictionary' пар ключ-значение в качестве аргументов post.Оооо ... в конечном итоге мы хотели бы что-то вроде этого:

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

И

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

Чтобы попытаться это сделать, я использую объект WWW.Теперь, чтобы дать WWW объекту время для загрузки, нам нужно, чтобы это происходило внутри MonoBehaviour объекта и yield результатов.Итак, я получил это, которое работает:

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

Что мне действительно нужно, так это:

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.   
    }
}

Теперь у меня есть основной скрипт, прикрепленный к единственному GameObject в иерархии (называется корень).Нужно ли подключать скрипт GET к корню GameObject?Могу ли я сделать это динамически от main?

В конечном счете, мне нужно решение, которое позволит мне легко отправлять GET и POST запросов.

Приветствия!

Ответы [ 3 ]

17 голосов
/ 21 января 2012

Ах, понял!

Моя проблема заключалась в неправильном понимании того, как MonoBehaviour и сопрограммы работали. Решение очень простое.

В редакторе создайте пустой GameObject. Я назвал это БД. Затем присоедините к нему следующий скрипт:

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<string, string> post)
    {
        WWWForm form = new WWWForm();
        foreach (KeyValuePair<String, String> 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);
        }
    }
}

Затем, в функции запуска вашего основного скрипта, вы можете сделать это!

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

Не проверял POST-запросы, но теперь вся логика свернута! Отправить HTTP-запросы на ваше желание сердца, ура!

2 голосов
/ 21 января 2012

Что это за сценарий GET, на который вы ссылаетесь? Класс WWW позволяет вам получать данные GET очень хорошо, необходимая информация находится в свойстве text экземпляра объекта WWW. Вот документация:

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

Все, что вам нужно сделать, это получить объект WWW, как вы это делаете сейчас, и затем прочитать любые интересующие вас свойства, простые и понятные, никаких дополнительных классов не требуется.

Что касается отправки объекта POST, для этого предназначен класс WWWForm:

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

Короче говоря, вы просто создаете объект WWWForm, добавляете к нему поля с помощью AddField (), а затем просто создаете новый объект WWW с URL-адресом POST и первым объектом, вот и все. Получите объект WWW, и как только он вернется, ваши данные будут отправлены. Ответы снова находятся в текстовом свойстве & ошибки в соответствующем поле. Простой, чистый и простой.

НТН!

0 голосов
/ 25 июня 2017

Вот код @ pandemoniumsyndicate, модифицированный для добавления обратного вызова. Исходный код не совсем корректен, так как функции GET и POST завершатся сразу после вызова сопрограммы. В то время вполне вероятно, что запрос WWW еще не завершен, и доступ к любому полю, кроме (www.isDone), не имеет смысла.

Следующий код определяет делегата, WWWRequestFinished, который будет вызываться по завершении запроса с результатом запроса и полученными данными, если таковые имеются.

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class WWWRequestor : MonoBehaviour 
{

    Dictionary<WWW, object> mRequestData = new Dictionary<WWW, object>();
    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<string, string> post, WWWRequestFinished pDelegate)
    {
        WWWForm aForm = new WWWForm();
        foreach (KeyValuePair<String, String> 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);
    }

}
...