實現Http請求的封裝,我們主要考慮的就是兩個問題:
所有的網絡通訊都寫在一個類裡,外部調用只考慮傳入參數即可,做到解耦效果
Unity的通訊是用協程方式實現網絡通訊,怎麼處理通訊返回的值後續的操作
第一個問題正常的封裝都會考慮到這個,這裡就不在說了,主要我們考慮的是第二個問題,因為是通過協程的方式處理網絡通訊,沒法實現我們正常封裝只方法給出返回值的方式實現,所以這裡應該用的就是傳入回調函數的方式處理。所以這篇我們就用Action的方式解決這個問題。using System;using System.Collections;using System.Collections.Generic;using System.Text;using UnityEngine;using UnityEngine.Networking;
public class HttpRestful : MonoBehaviour{ private static HttpRestful _instance;
public static HttpRestful Instance { get { if(_instance == null) { GameObject goRestful = new GameObject("HttpRestful"); _instance = goRestful.AddComponent<HttpRestful>(); } return _instance; } }
#region Get請求 public void Get(string url, Action<bool, string> actionResult = null) { StartCoroutine(_Get(url, actionResult)); }
private IEnumerator _Get(string url, Action<bool, string> action) { using (UnityWebRequest request = UnityWebRequest.Get(url)) { yield return request.SendWebRequest();
string resstr = ""; if (request.isNetworkError || request.isHttpError) { resstr = request.error; } else { resstr = request.downloadHandler.text; }
if (action != null) { action(request.isHttpError, resstr); } } } #endregion
#region POST請求 public void Post(string url, string data, Action<bool, string> actionResult = null) { StartCoroutine(_Post(url, data, actionResult)); }
private IEnumerator _Post(string url, string data, Action<bool, string> action) { using (UnityWebRequest request = new UnityWebRequest(url, "POST")) { request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data)); request.SetRequestHeader("content-type", "application/json;charset=utf-8"); request.downloadHandler = new DownloadHandlerBuffer();
yield return request.SendWebRequest();
string resstr = ""; if (request.isNetworkError || request.isHttpError) { resstr = request.error; } else { resstr = request.downloadHandler.text; }
if (action != null) { action(request.isHttpError, resstr); } } } #endregion}
我們重新複製了一個UIScripts,然後其中一個名字後面加上了Old,這樣就是不用再重新設置了,我們直接在UIScripts腳本中改造即可。
首先定義一個Action<bool, string>,其中參數和HttpRestful裡傳入的Action方法是一樣的。
然後增加一個InitAction的方法,裡面對定義的actionRes寫其的實現方法。方法中就是判斷通訊如果失敗直接顯示文本,成功後進行處理,再顯示處理後的數據,因為Get和Post調用後返回的數據類型是一樣的,這樣我們這裡寫了一個Action都可以調用這個方法進行後面的數據處理。
然後我們在Start裡面首先把初始化Action進行調用,然後使用HttpRestful.Instance.Get(url, actionRes);HttpRestful.Instance.Post(url, json, actionRes);就可以直接進行數據處理了,剩下的我們昨天調用的方法就可以都刪除了。using System;using System.Collections;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;using UnityEngine;using UnityEngine.Networking;using UnityEngine.UI;
public class UIScripts : MonoBehaviour{ [Header("按鈕")] public Button btnget; public Button btngetparm; public Button btnjson; public Button btnpost;
[Space] [Header("顯示")] public Text txtshow;
[Space] [Header("輸入框")] public InputField edturl; public InputField edtparm;
private Action<bool, string> actionRes; void Start() { InitAction();
btnget.onClick.AddListener(() => { Debug.Log(edturl.text); string url = edturl.text; HttpRestful.Instance.Get(url, actionRes); }); btngetparm.onClick.AddListener(() => { string url = edturl.text; string param = edtparm.text;
string allurl = url + "/Info?Summary=" + param; HttpRestful.Instance.Get(allurl, actionRes); });
btnjson.onClick.AddListener(() => StartCoroutine(JsonConvert()));
btnpost.onClick.AddListener(() => { WeatherForecast item = new WeatherForecast(); item.Summary = "Alvin"; item.Date = DateTime.Now; item.TemperatureC = 10; item.TemperatureF = 20; string json = JsonUtility.ToJson(item);
string url = edturl.text + "/Reg"; Debug.Log(url); HttpRestful.Instance.Post(url, json, actionRes); }); }
private void InitAction() { actionRes = new Action<bool, string>((bl, str) => { if (bl) { txtshow.text = str; } else { string resjson = "{\"array\":" + str + "}"; txtshow.text = resjson; WeatherData lists = JsonUtility.FromJson<WeatherData>(resjson); StringBuilder sb = new StringBuilder(); foreach (WeatherForecast item in lists.array) { sb.Append("Date:" + item.Date + " Summary:" + item.Summary + " TemperatureF:" + item.TemperatureF + "TemperatureC:" + item.TemperatureC + "\r\n"); } txtshow.text = sb.ToString(); } }); }
IEnumerator JsonConvert() { WeatherForecast item = new WeatherForecast(); item.Summary = "Alvin"; item.Date = DateTime.Now; item.TemperatureC = 10; item.TemperatureF = 20;
string json = JsonUtility.ToJson(item); txtshow.text = json; yield return new WaitForSeconds(3f);
WeatherForecast newitem = JsonUtility.FromJson<WeatherForecast>(json); string showtext = "Summary:" + newitem.Summary + " Date:" + newitem.Date + " C:" + newitem.TemperatureC + " F:" + newitem.TemperatureF; txtshow.text = showtext; }}上圖就是封裝後調用WebApi的實現效果,後面我又在Android平臺下進行了編譯,調用也完全沒有問題,這種方式可以跨平臺使用的。