使用Unity在C#中发送http请求

Kam*_*ian 24 c# http unity-game-engine

如何使用Unity在C#中发送HTTP GET和POST请求?

我想要的是:

  • 在post请求中发送json数据(我使用Unity序列化器,因此不需要新的,我只想在post数据中传递字符串并且能够将ContentType设置为application/json);
  • 获得响应代码和正文没有任何问题;
  • 在不阻止ui渲染的情况下完成异步操作.

我尝试过的:

  • 使用HttpWebRequest/HttpWebResponse实现,但它太难和低级别(如果我找不到更好的东西,我将不得不使用它);
  • 使用统一WWW,但它不符合我的要求;
  • 使用NuGet的一些外部包 - Unity不接受它们:(

大多数问题都是使用线程,我在C#中没有足够的经验.我使用的文本编辑器是Intellij Rider.

Pro*_*mer 62

WWWAPI应该完成这件事,但UnityWebRequest取而代之,所以我会回答新的API.这很简单.您必须使用协同程序使用Unity的API执行此操作,否则您必须使用C#标准Web请求API和线程之一.使用协程,您可以在完成之前提出请求.这不会阻止主线程或阻止其他脚本运行.

注意:

对于下面的示例,如果您使用Unity 2017.2以下的任何内容,请替换SendWebRequest()Send(),然后替换isNetworkErrorisError.这将适用于较低版本的Unity.此外,如果您需要以二进制形式访问下载的数据,请替换uwr.downloadHandler.textuwr.downloadHandler.data.最后,该SetRequestHeader函数用于设置请求的标头.

GET请求:

void Start()
{
    StartCoroutine(getRequest("http:///www.yoururl.com"));
}

IEnumerator GetRequest(string uri)
{
    UnityWebRequest uwr = UnityWebRequest.Get(uri);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}
Run Code Online (Sandbox Code Playgroud)

表格的POST请求:

void Start()
{
    StartCoroutine(postRequest("http:///www.yoururl.com"));
}

IEnumerator PostRequest(string url)
{
    WWWForm form = new WWWForm();
    form.AddField("myField", "myData");
    form.AddField("Game Name", "Mario Kart");

    UnityWebRequest uwr = UnityWebRequest.Post(url, form);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用Json的POST请求:

 void Start()
 {
     StartCoroutine(postRequest("http:///www.yoururl.com", "your json"));
 }

 IEnumerator PostRequest(string url, string json)
 {
     var uwr = new UnityWebRequest(url, "POST");
     byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json);
     uwr.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
     uwr.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
     uwr.SetRequestHeader("Content-Type", "application/json");

     //Send the request then wait here until it returns
     yield return uwr.SendWebRequest();

     if (uwr.isNetworkError)
     {
         Debug.Log("Error While Sending: " + uwr.error);
     }
     else
     {
         Debug.Log("Received: " + uwr.downloadHandler.text);
     }
 }
Run Code Online (Sandbox Code Playgroud)

使用Multipart FormData/Multipart表单文件的POST请求:

void Start()
{
    StartCoroutine(postRequest("http:///www.yoururl.com"));
}

IEnumerator PostRequest(string url)
{
    List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
    formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));

    UnityWebRequest uwr = UnityWebRequest.Post(url, formData);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}
Run Code Online (Sandbox Code Playgroud)

PUT请求:

void Start()
{
    StartCoroutine(putRequest("http:///www.yoururl.com"));
}

IEnumerator PutRequest(string url)
{
    byte[] dataToPut = System.Text.Encoding.UTF8.GetBytes("Hello, This is a test");
    UnityWebRequest uwr = UnityWebRequest.Put(url, dataToPut);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Received: " + uwr.downloadHandler.text);
    }
}
Run Code Online (Sandbox Code Playgroud)

删除请求:

void Start()
{
    StartCoroutine(deleteRequest("http:///www.yoururl.com"));
}

IEnumerator DeleteRequest(string url)
{
    UnityWebRequest uwr = UnityWebRequest.Delete(url);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Error While Sending: " + uwr.error);
    }
    else
    {
        Debug.Log("Deleted");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 就像我说的那样,`UnityWebRequest`被实现为在另一个Thread中运行.coroutine用于等待/屈服于它完成请求.收益率意味着等待'UnityWebRequest`,这是**另一个线程**完成.屈服时它不会阻塞主线程.这就是协同程序很棒的原因. (3认同)
  • 我的示例演示了如何使用json创建http请求.如果您按原样复制json示例并粘贴到编辑器**而不**修改它,它应该工作.如果您修改它并且它不起作用,请创建一个新问题.在您创建新问题之前,我想告诉您我在您的代码中发现的问题.`execute`是一个协程函数,不应该像你那样直接调用.应该使用`StartCoroutine(execute())`函数调用它.再看看我的例子.你必须添加`yield return uwr.SendWebRequest();`否则你将来会遇到问题. (2认同)
  • 最后,具有coroutine(`execute`)函数**的类必须**继承自`MonoBehaviour`,然后才能使用`StartCoroutine`函数启动协程函数.你的班级不会继承"MonoBehaviour".如果您不想继承"MonoBehaviour",请参阅我的回答[这里](/sf/answers/2835638291/),因为我描述了如何执行此操作**而没有**继承自`MonoBehaviour `.请在回复此评论之前解决所有这些问题.如果您遇到问题,请提出新问题,但在该问题中发布您的代码. (2认同)
  • @Bluetree是的,它应该适用于Unity支持的任何平台. (2认同)
  • @Bluetree我的答案就在那里.在那一秒下看到`MultipartFormFileSection`.看到它的许多构造函数重载[这里](https://docs.unity3d.com/ScriptReference/Networking.MultipartFormFileSection-ctor.html). (2认同)