ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-06-25 13:04:00  阅读:238  来源: 互联网

标签:引擎 callback JObject 博客 发送 url Unity webRequest UnityWebRequest


利用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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有