其他分享
首页 > 其他分享> > 【技术博客】Unity引擎发送网络请求的方法

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

作者:互联网

利用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;
    ...
});

标签:引擎,callback,JObject,博客,发送,url,Unity,webRequest,UnityWebRequest
来源: https://www.cnblogs.com/hair-duang-duang/p/16411155.html