使用 UnityWebRequest 进行简单的 HTTP (POST) 通信

感谢你们的辛勤工作。
我是系统开发部的松山。
这次我将介绍如何使用 UnitWebRequest 进行 HTTP (POST) 通信。
虽然可能有点晚了,但我之前只实现了通过 www 进行的通信,所以我会再写一遍 ^^;
做什么
・使用 UnitWebRequest 进行 HTTP (POST) 通信
・请求和响应采用
JSON 格式・简单,假设将创建多个通信 API
※ 使用 Unity 2019.3.5f1 创建
JSON
首先,我们来看看 JSON。我们将使用 Unity 的 JsonUtility 来实现它。JsonUtility
是 Unity 提供的一个 JSON 解析器,它
可以轻松序列化指定为 Serializable 的类和结构。
虽然它有一些限制,例如不支持 Dictionary 类型,但它的性能似乎优于其他 JSON 解析器。
序列化为 JSON 格式
UnityWebRequest
是主要的通信过程。UnityWebRequest
可以处理 HTTP 请求和响应。
整个过程非常简单。
创建一个 POST 格式的 UnityWebRequest 请求,并以 JSON 格式设置请求参数。
// 设置 HTTP (POST) 信息 var req = new UnityWebRequest(url, "POST"); req.uploadHandler = (UploadHandler)new UploadHandlerRaw(postData); req.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); req.SetRequestHeader("Content-Type", "application/json");
需要注意的是,该参数不能作为字符串传递,因此您需要将其转换为字节数组。
// 将请求对象转换为 JSON(字节数组)字符串 reqJson = JsonUtility.ToJson(request); byte[] postData = System.Text.Encoding.UTF8.GetBytes(reqJson);
准备就绪后,请提交您的申请。
// API 通信(等待完成) yield return req.SendWebRequest();
如果 isNetworkError 和 isHttpError 都为 false,则判定通信成功。
响应以 JSON 格式(文本)存储在 downloadHandler 中。
// 通信结果 if (req.isNetworkError || req.isHttpError) // 失败 { Debug.Log("网络错误:" + req.error); } else // 成功 { Debug.Log("下载成功:" + req.downloadHandler.text); }
API 控制
其思路是创建一个 API 类,该类使用上述通信流程作为基类,定义每个 API 的请求和响应。
具体来说,流程如下:
创建一个带有 Serializable 属性的请求和响应结构,并定义参数。
通信过程中使用的 URL 的公共部分在基类中定义,因此 API 名称放在最后。
using System; using System.Collections.Generic; namespace Api { ///<summary> /// API 示例 B ///</summary> public class SampleB : Web.ApiBase { public const string Name = "Test/SampleB"; ///<summary> /// 请求参数 ///</summary> [Serializable] public struct Request { public string userId; public List<int> values; } public Request request; ///<summary> /// 响应参数 ///</summary> [Serializable] public struct Response { public int count; public List<int> values; } public Response response; } }
如何使用
首先,生成上面提到的API类。
private Api.SampleB apiB; private Web.ApiBase.Result result; private void Start() { // 创建一个用于通信的类 apiB = new Api.SampleB(); // API 通信 sendApiB(); }
指定 API 名称后,设置要传递给请求结构的值。该值
在 Send() 方法中被序列化为 JSON 格式,并通过 UnityWebRequest 使用 HTTP (POST) 请求进行通信。
通信完成时,会通过回调函数接收该值,并将其反序列化到响应结构中。
通常情况下,您需要根据响应内容编写处理代码,但由于这是一个示例,因此仅将其输出到控制台。
///<summary> /// API 示例 B 通信 ///</summary> private void sendApiB() { // 设置端点 apiB.EndPoint = Api.SampleB.Name; // 设置请求参数 apiB.request.userId = "beyondB"; apiB.request.values = new List<int> () { 1, 10, 100, 1000 }; // 通信 apiB.Send<Api.SampleB.Request> (ref apiB.request, result => { // 结果 if (result.isSucceeded) // 成功 { // 提取响应 apiB.response = apiB.Response<Api.SampleB.Response> (); // 检查内容 Debug.Log("SampleB 成功!"); Debug.Log("计数:" + apiB.response.count); foreach(var v in apiB.response.values) { Debug.Log("值:" + v); } } else // 失败 { Debug.Log("SampleB 失败:" + result.error); } }); }
概括
这样,我就编写了一个相当简单的 HTTP 通信流程。
我认为目前来说它足够实用。
由于这是一个通信流程,如果没有服务器端实现,它是无法工作的,但我已经将示例代码上传到了 GitHub。Unity
示例
示例的基类没有继承 MonoBehaviour,因此无法直接使用协程。
解决方法请参考:
在未继承 MonoBehaviour 的类中使用协程
最后
我是系统开发服务网站“SEKARAKU Lab”的成员。Beyond
提供从服务器设计、搭建到运维的一站式服务,如果您在服务器端开发方面遇到任何问题,欢迎随时联系我们。SEKARAKU
Lab: [https://sekarakulab.beyondjapan.com/](https://sekarakulab.beyondjapan.com/)
好了,今天就到这里。
3