Bootstrap

Unity之UnityWebRequest

介绍

unity中使用UnityWebRequest来代替所有HTTP请求提供了三种API,UnityWebRequest.Get,UnityWebRequest.Post,UnityWebRequest.Put分别处理GET,POST,PUT请求。UnityWebRequest需要配合协程使用,所有HTTP请求都是异步的,可以方便监听请求结果,默认情况支持HTTPS,如果需要支持HTTP,则需要单独开启,Player Settings中需要Allow downkiads over HTTP。

基本代码如下所示:

IEnumerable Start()
    {
        //GET请求
        UnityWebRequest quest01 = UnityWebRequest.Get("http://www.baidu.com");
        yield return quest01.SendWebRequest();
        var data01 = quest01.downloadHandler.text;

        //POST请求
        WWWForm form = new WWWForm();
        form.AddField("", "");
        UnityWebRequest quest02 = UnityWebRequest.Post("http://www.baidu.com", form);
        yield return quest02.SendWebRequest();
        var data02 = quest01.downloadHandler.text;

        //PUT请求
        byte[] myData = Encoding.UTF8.GetBytes("Test");
        UnityWebRequest quest03 = UnityWebRequest.Put("http://www.baidu.com",myData);
        yield return quest03.SendWebRequest();
        var data03 = quest03.downloadHandler.text;
    }

下载文件和上传文件

UnityWebRequest配合DownloadHandler可以处理下载文件,配合一下UploadHandler可以处理上传文件,但是下载文件的类型比较多,Unity又进一步封装,代码如下:

  //下载二进制文件
        UnityWebRequest request04 = UnityWebRequest.Get("");
        request04.downloadHandler = new DownloadHandlerFile("");
        yield return request04.SendWebRequest();
        byte[] data04 = request04.downloadHandler.data;

        //下载AB包
        UnityWebRequest quest05 = UnityWebRequest.Get("");
        quest05.downloadHandler = new DownloadHandlerAssetBundle("",0);
        yield return quest05.SendWebRequest();
        AssetBundle ab = ((DownloadHandlerAssetBundle)quest05.downloadHandler).assetBundle;

        //上传本地文件
        var questLoad = new UnityWebRequest("", UnityWebRequest.kHttpVerbPUT);
        questLoad.uploadHandler = new UploadHandlerFile("");
        yield return questLoad.SendWebRequest();

        //           .
        //           .
        //           .
        //           .
        //           .
        //           .
        //           .

下载进度和异常

下载过程中如果下载一个大文件,还需要处理下载异常并并显示下载进度,如下代码所示:

 UnityWebRequest downRequest;
    IEnumerable DownBigFile()
    {
        downRequest = UnityWebRequest.Get("url");
        downRequest.downloadHandler = new DownloadHandlerFile("");
        yield return downRequest.SendWebRequest();

        if (downRequest.result == UnityWebRequest.Result.Success)
        {
            Debug.Log("下载成功");
        }
        else {

            Debug.Log("下载失败, 错误信息为:" + downRequest.error);
            
        }
    }


    void Update()
    {
        if (downRequest!=null)
        {
            Debug.Log("下载进度为:" + downRequest.downloadProgress + "  已下载大小为:" + downRequest.downloadedBytes);
        }
    }

验证文件

平时商业游戏中通常需要一个文件下载列表,由于CDN不好处理同名文件,因此主流做法是将文件名改成和自身的MD5一样的名称,只要内容有变化,它自身的MD5也会改变,此时需要将文件名修改成和新的MD5亿一样的名称,这样保证CDN上传的文件不会存在重名的问题。
文件下载需要考虑文件完整性,通常是在上传前将文件MD5和文件大小保存起来,用户下载完成后需要检查当前的下载大小和MD5是否与CDN上的一致,由于设备获取MD5比较慢,通常只会保存文件大小,如果下载前后出现不一致,需要将本地文件删除,重新下载。

DownloadHandlerScript

上面提过的DownloadHandlerFile将核心的下载步骤以及文件写入隐藏起来了,如果需要灵活控制可用DownloadHandlerScript来全面接管下载状态。如下代码所示:

public class CuetomDownLoadHandler : DownloadHandlerScript {

    FileStream fileStream;
    int reciveLength = 0;
    ulong contentLength;
    public CuetomDownLoadHandler(string path, byte[] prealocateBuffer): base(prealocateBuffer)
    {
        int size = prealocateBuffer.Length;
        fileStream = new FileStream(path, FileMode.OpenOrCreate,FileAccess.Write,FileShare.Write,size);
    }

    protected override bool ReceiveData(byte[] data, int dataLength)
    {

        if (data==null||data.Length<1)
        {
            return false;
        }

        reciveLength += dataLength;
        fileStream.Write(data, 0, dataLength);

        return base.ReceiveData(data, dataLength);
    }

    protected override float GetProgress()
    {
        return (float)reciveLength/(float)contentLength;
    }

    protected override void ReceiveContentLengthHeader(ulong contentLength)
    {
        this.contentLength = Math.Max(0, contentLength);
    }


    protected override void CompleteContent()
    {
        Dispose();
    }

   new  public void Dispose() {
        if (fileStream!=null)
        {
            fileStream.Dispose();
            fileStream = null;
        }

        base.Dispose();
    }

只需将DownloadHandlerFile代码替换上述CuetomDownLoadHandler就可以了


目前总结这么多,如果错误,欢迎指正!!!

Passion!!!

;