利用Unity引擎发送请求的方法
使用Unity发送请求,主要用到UnityWebRequest这个类。灵境中使用了两种办法发送请求。
以JSON格式发送请求
使用Newtonsoft.Json中的JObject类管理JSON数据。具体使用方法请查阅官网https://www.newtonsoft.com/json。示例:var data = new JObject(); data["xxx"] = xxx;
使用本方法需要使用Unity的协程函数StartCoroutine,调用示例为StartCoroutine(SendRequest(data, url, callback, "POST"));- // 定义回调函数
- delegate void SendRequestCallback(JObject returnData);
- /// <summary>
- /// 本方法将以Json格式向后端发送请求
- /// </summary>
- /// <param name="originJson">要发送的Json对象</param>
- /// <param name="url"></param>
- /// <param name="call">回调函数,不会处理异常,将信息原样返回</param>
- /// <param name="type">可以是"POST"、"GET"等</param>
- IEnumerator SendRequest(JObject originJson, string url, SendRequestCallback callback, string type)
- {
- // 将JObject转成json字符串
- string sendData = JsonConvert.SerializeObject(originJson);
- // 将字符串使用UTF-8编码成字节流
- byte[] postBytes = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(sendData);
-
- // 创建UnityWebRequest对象,用以发送请求。使用type指定请求的类型。
- using (UnityWebRequest webRequest = new UnityWebRequest(url, type))
- {
- // 设置要上传的数据
- webRequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
- // 创建后端返回数据的接收端
- webRequest.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
- // 添加请求头。token是我们项目特有的
- webRequest.SetRequestHeader("xxx", xxx);
- // 必须要添加Content-Type请求头,明确指定以json形式传输
- webRequest.SetRequestHeader("Content-Type", "application/json");
- // 发送请求,并等待后端返回后继续调用。
- yield return webRequest.SendWebRequest();
- // 当后端炸了,可能返回一个空字符串,对空字符串进行json解析会导致错误
- if (string.IsNullOrEmpty(webRequest.downloadHandler.text))
- {
- callback(null);
- } else
- {
- // 将后端返回的json字符串转换成一个JObject对象,使用callback传递。
- JObject returnData = JObject.Parse(webRequest.downloadHandler.text);
- callback(returnData);
- }
- }
- }
复制代码 可以看出,发送请求的时候实际只是发送了一个字节流,因此这种方法的灵活度是最高的,不止可以发送json字符串,理论上可以以任何形式发送任何数据。
以表格Form的形式发送数据
整体逻辑与上面的基本相同,但是unity对此封装的较为完善,步骤更简略,灵活度也更低。
使用WWWForm类存储数据,使用方法可以参见:https://docs.unity3d.com/cn/2019.4/ScriptReference/WWWForm.html。示例:var form = new WWWForm(); form.AddField("xxx", xxx);
使用Form形式可以发送二进制数据,可以用来上传图片,如form.AddBinaryData("file", texture.EncodeToJPG());。有时候后端即需要二进制数据,同时有需要一些参数,那么以Form的形式发送将变得十分方便。- IEnumerator UploadForm(WWWForm form, string url, SendRequestCallback callback)
- {
- // 可以直接指定以POST形式发送,也可以是其他形式。构造函数中直接传递WWWForm,不用进行字节流的转换等工作。
- using (UnityWebRequest webRequest = UnityWebRequest.Post(url, form))
- {
- // 添加请求头。
- webRequest.SetRequestHeader("xxx", xxx);
- // 发送请求并等待返回
- yield return webRequest.SendWebRequest();
- // 与之前逻辑相同,不再赘述
- if (string.IsNullOrEmpty(webRequest.downloadHandler.text))
- {
- callback(null);
- }
- else
- {
- JObject returnData = JObject.Parse(webRequest.downloadHandler.text);
- callback(returnData);
- }
- }
- }
复制代码 从URL下载图片
- delegate void DownloadImageCallback(Sprite image);
- /// <summary>
- /// 下载图片,转换成sprite的格式并传递给callback.
- /// 如果网络出错,就传一个null
- /// 目前验证过的图片格式:PNG, JPG
- /// </summary>
- /// <param name="url">图片的url</param>
- /// <param name="callback"></param>
- IEnumerator DownloadImage(string url, DownloadImageCallback callback)
- {
- using (UnityWebRequest webRequest = new UnityWebRequest(url))
- {
- // 将UnityWebRequest处理下载数据的类设置为DownloadHandlerTexture
- // 之前用的是DownloadHandlerBuffer
- DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
- webRequest.downloadHandler = texDl;
- // 发送请求
- yield return webRequest.SendWebRequest();
-
- // 为了提高方法的间接性,不让用户自己处理网络错误了。回调函数只会传递sprite
- if (webRequest.result != UnityWebRequest.Result.ConnectionError
- && webRequest.result != UnityWebRequest.Result.ProtocolError)
- {
- // 没有网络错误,将下载的图片转换成sprite给回调函数
- Sprite sprite = Sprite.Create(texDl.texture, new Rect(0, 0, texDl.texture.width, texDl.texture.height), new Vector2(0.5f, 0.5f));
- callback(sprite);
- } else
- {
- // 出现网络错误,传一个null
- callback(null);
- }
- }
- }
复制代码 使用以上函数的方法
以上方法均需要使用Unity的``StartCoroutine方法,因此不能写成静态类,必须要继承MonoBehaviour`类然后挂到一个游戏物体上。
可以将以上方法封装为一个RequestSender类,``StartCoroutine`写到这个类的里面,然后其他脚本想要发送请求,就可以借助匿名方法,用如下这种简便的方法发送请求:- // 以JSON发送POST请求
- string url = "xxx";
- JObject data = new JObject();
- data["xxx"] = xxx;
- FindObjectOfType<RequestSender>().SendPostRequest(data, url, (JObject returnData) => {
- // 处理网络异常
- if (returnData.Value<int>("code") != 0) {
- Debug.Log("ERROR!");
- return;
- }
- // 数据一般都会放在data段里
- returnData = returnData.Value<JObject>("data");
- Debug.Log(returnData.ToString());
- ...
- });
-
- // 从url下载图片
- FindObjectOfType<RequestSender>().DownloadImage(url, (Sprite sprite) => {
- // 处理异常
- if (sprite = null) {
- Debug.Log("ERROR!");
- return;
- }
- // 比如下载图片后设置为头像
- portrait.sprite = sprite;
- ...
- });
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |