【技术博客】Unity引擎发送网络请求的方法

打印 上一主题 下一主题

主题 504|帖子 504|积分 1512

利用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"));
  1. // 定义回调函数
  2. delegate void SendRequestCallback(JObject returnData);
  3. /// <summary>
  4. /// 本方法将以Json格式向后端发送请求
  5. /// </summary>
  6. /// <param name="originJson">要发送的Json对象</param>
  7. /// <param name="url"></param>
  8. /// <param name="call">回调函数,不会处理异常,将信息原样返回</param>
  9. /// <param name="type">可以是"POST"、"GET"等</param>
  10. IEnumerator SendRequest(JObject originJson, string url, SendRequestCallback callback, string type)
  11. {
  12.     // 将JObject转成json字符串
  13.     string sendData = JsonConvert.SerializeObject(originJson);
  14.     // 将字符串使用UTF-8编码成字节流
  15.     byte[] postBytes = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(sendData);
  16.    
  17.     // 创建UnityWebRequest对象,用以发送请求。使用type指定请求的类型。
  18.     using (UnityWebRequest webRequest = new UnityWebRequest(url, type))
  19.     {
  20.         // 设置要上传的数据
  21.         webRequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
  22.         // 创建后端返回数据的接收端
  23.         webRequest.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
  24.         // 添加请求头。token是我们项目特有的
  25.         webRequest.SetRequestHeader("xxx", xxx);
  26.         // 必须要添加Content-Type请求头,明确指定以json形式传输
  27.         webRequest.SetRequestHeader("Content-Type", "application/json");
  28.                 // 发送请求,并等待后端返回后继续调用。
  29.         yield return webRequest.SendWebRequest();
  30.         // 当后端炸了,可能返回一个空字符串,对空字符串进行json解析会导致错误
  31.         if (string.IsNullOrEmpty(webRequest.downloadHandler.text))
  32.         {
  33.             callback(null);
  34.         } else
  35.         {
  36.             // 将后端返回的json字符串转换成一个JObject对象,使用callback传递。
  37.             JObject returnData = JObject.Parse(webRequest.downloadHandler.text);
  38.             callback(returnData);
  39.         }
  40.     }
  41. }
复制代码
可以看出,发送请求的时候实际只是发送了一个字节流,因此这种方法的灵活度是最高的,不止可以发送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的形式发送将变得十分方便。
  1. IEnumerator UploadForm(WWWForm form, string url, SendRequestCallback callback)
  2. {
  3.     // 可以直接指定以POST形式发送,也可以是其他形式。构造函数中直接传递WWWForm,不用进行字节流的转换等工作。
  4.     using (UnityWebRequest webRequest = UnityWebRequest.Post(url, form))
  5.     {
  6.         // 添加请求头。
  7.         webRequest.SetRequestHeader("xxx", xxx);
  8.         // 发送请求并等待返回
  9.         yield return webRequest.SendWebRequest();
  10.         // 与之前逻辑相同,不再赘述
  11.         if (string.IsNullOrEmpty(webRequest.downloadHandler.text))
  12.         {
  13.             callback(null);
  14.         }
  15.         else
  16.         {
  17.             JObject returnData = JObject.Parse(webRequest.downloadHandler.text);
  18.             callback(returnData);
  19.         }
  20.     }
  21. }
复制代码
从URL下载图片
  1. delegate void DownloadImageCallback(Sprite image);
  2. /// <summary>
  3. /// 下载图片,转换成sprite的格式并传递给callback.
  4. /// 如果网络出错,就传一个null
  5. /// 目前验证过的图片格式:PNG, JPG
  6. /// </summary>
  7. /// <param name="url">图片的url</param>
  8. /// <param name="callback"></param>
  9. IEnumerator DownloadImage(string url, DownloadImageCallback callback)
  10. {
  11.     using (UnityWebRequest webRequest = new UnityWebRequest(url))
  12.     {
  13.         // 将UnityWebRequest处理下载数据的类设置为DownloadHandlerTexture
  14.         // 之前用的是DownloadHandlerBuffer
  15.         DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
  16.         webRequest.downloadHandler = texDl;
  17.         // 发送请求
  18.         yield return webRequest.SendWebRequest();
  19.         
  20.         // 为了提高方法的间接性,不让用户自己处理网络错误了。回调函数只会传递sprite
  21.         if (webRequest.result != UnityWebRequest.Result.ConnectionError
  22.             && webRequest.result != UnityWebRequest.Result.ProtocolError)
  23.         {
  24.             // 没有网络错误,将下载的图片转换成sprite给回调函数
  25.             Sprite sprite = Sprite.Create(texDl.texture, new Rect(0, 0, texDl.texture.width, texDl.texture.height), new Vector2(0.5f, 0.5f));
  26.             callback(sprite);
  27.         } else
  28.         {
  29.             // 出现网络错误,传一个null
  30.             callback(null);
  31.         }
  32.     }
  33. }
复制代码
使用以上函数的方法

以上方法均需要使用Unity的``StartCoroutine方法,因此不能写成静态类,必须要继承MonoBehaviour`类然后挂到一个游戏物体上。
可以将以上方法封装为一个RequestSender类,``StartCoroutine`写到这个类的里面,然后其他脚本想要发送请求,就可以借助匿名方法,用如下这种简便的方法发送请求:
  1. // 以JSON发送POST请求
  2. string url = "xxx";
  3. JObject data = new JObject();
  4. data["xxx"] = xxx;
  5. FindObjectOfType<RequestSender>().SendPostRequest(data, url, (JObject returnData) => {
  6.     // 处理网络异常
  7.     if (returnData.Value<int>("code") != 0) {
  8.         Debug.Log("ERROR!");
  9.         return;
  10.     }
  11.     // 数据一般都会放在data段里
  12.     returnData = returnData.Value<JObject>("data");
  13.     Debug.Log(returnData.ToString());
  14.     ...
  15. });
  16.    
  17. // 从url下载图片
  18. FindObjectOfType<RequestSender>().DownloadImage(url, (Sprite sprite) => {
  19.     // 处理异常
  20.     if (sprite = null) {
  21.         Debug.Log("ERROR!");
  22.         return;
  23.     }
  24.     // 比如下载图片后设置为头像
  25.     portrait.sprite = sprite;
  26.     ...
  27. });
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小小小幸运

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表