Unity-Http协议请求下载系列3:UnityWebRequest

40 篇文章 3 订阅

上篇文章介绍了基于HttpWebRequest接口实现的资源请求下载方案,本篇介绍基于UnityWebRequest接口实现的方案。并且是开启协程执行的。

首先,写一个全局的协程管理控制器CoroutineManager工具类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
 * Author:W
 * 线程工具【全局】
 */
namespace W.GameFramework.HotUpdate
{	
	public class CoroutineManager : MonoBehaviour
	{		
		private static CoroutineManager _instance;
		public static CoroutineManager Instance
		{
			get
			{
				if (_instance == null)
				{
					GameObject coroutineManagerObj = new GameObject("CoroutineTool");
					coroutineManagerObj.name = "CoroutineTool";
					GameObject.DontDestroyOnLoad(coroutineManagerObj);

					_instance = coroutineManagerObj.AddComponent<CoroutineManager>();					
				}

				return _instance;
			}
		}

		void Awake()
		{
			if (_instance != null)
			{
				GameObject.Destroy(this.gameObject);
			}
		}


		/// <summary>
		/// 开启全局协程执行某函数
		/// </summary>
		/// <param name="delegateMethod"></param>
		public void StartGlobalCoroutine(IEnumerator delegateMethod)
		{			
			StartCoroutine(delegateMethod);
		}

		/// <summary>
		/// 关闭全局协程
		/// </summary>
		/// <param name="delegateMethod"></param>
		public void StopGlobalCoroutine(IEnumerator delegateMethod)
		{
			StopCoroutine(delegateMethod);
		}

		/// <summary>
		/// 停止所有的协程
		/// </summary>
		public void StopAllGlobalCoroutines()
		{
			StopAllCoroutines();
		}
	}
}

然后是核心类UnityWebRequestHelper的实现

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.IO;

/*
* Author:W
* Unity引擎网络请求下载接口封装
*/
namespace W.GameFramework.HotUpdate
{
   
    public class UnityWebHttpRequestHelper: HttpHelper
	{
        private FileStream fileStream = null;
        private UnityWebRequest headRequest = null;
        private UnityWebRequest webRequest = null;

        public override void SendHttpRequest(string url, string path, DownloadType downloadType = DownloadType.New, OnDownloadBeginHandler onDownloadBeginHandler = null, OnDownloadEndHandler onDownloadEndHandler = null,
            OnDownloadProgressHanlder onDownloadProgressHanlder = null, OnDownloadErrorHandler onDownloadErrorHandler = null)
        {
            base.SendHttpRequest(url, path, downloadType, onDownloadBeginHandler, onDownloadEndHandler,onDownloadProgressHanlder, onDownloadErrorHandler);
          
            CoroutineManager.Instance.StartGlobalCoroutine(SendUnityWebHttpRequest());
        }

        /// <summary>
        /// 开启协程请求下载资源
        /// </summary>
        /// <returns></returns>
        IEnumerator SendUnityWebHttpRequest()
        {
            //先发一次请求,只获取关于资源大小的Head
            headRequest = UnityWebRequest.Head(url);
            yield return headRequest.SendWebRequest();

            if (headRequest.isNetworkError || headRequest.isHttpError)
            {
                if (OnDownloadErrorHandler != null)
                    OnDownloadErrorHandler(headRequest.error);
            }
            else
            {               
                fileLength = long.Parse(headRequest.GetResponseHeader("Content-Length"));
               
                if (downloadType == DownloadType.New)
                {
                    if (File.Exists(path))
                        File.Delete(path);
                }

                fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);

                fileCurLength = fileStream.Length;
                progress = (float)fileCurLength / fileLength;

                if (OnDownloadBeginHandler != null)
                    OnDownloadBeginHandler();

                //当前请求下载的资源未完成下载,继续下载
                if (fileCurLength < fileLength)
                {
                    fileStream.Seek(fileCurLength, SeekOrigin.Begin);

                    webRequest = UnityWebRequest.Get(url);
                    webRequest.SetRequestHeader("Range", "bytes=" + fileCurLength + "-" + fileLength);
                    
                    webRequest.SendWebRequest();

                    if (webRequest.isNetworkError || webRequest.isHttpError)
                    {
                        if (OnDownloadErrorHandler != null)
                            OnDownloadErrorHandler(webRequest.error);
                    }
                    else
                    {
                        var index = 0;
                        
                        while (fileCurLength < fileLength)
                        {
                            //停止请求下载
                            if (IsStop)
                            {
                                Clear();
                                break;
                            }

                            yield return null;                                                        
                            var buff = webRequest.downloadHandler.data;                            
                            if (buff != null)
                            {
                                var length = buff.Length - index;
                                fileStream.Write(buff, index, length);
                                index += length;

                                fileCurLength += length;
                                progress = (float)fileCurLength / fileLength;                               
                            }                           
                        }
                    }                   
                }
                else
                {
                    progress = 1f;
                    if (OnDownloadEndHandler != null)
                        OnDownloadEndHandler();
                }

                Clear();           
            }

           

        }


        public override void Clear()
        {
            if (fileStream != null)
            {
                fileStream.Flush();
                fileStream.Close();

                fileStream = null;
            }

            if (webRequest != null)
            {
                webRequest.Abort();
                webRequest = null;
            }


            if (headRequest != null)
            {
                headRequest.Abort();
                headRequest = null;
            }

            CoroutineManager.Instance.StopGlobalCoroutine(SendUnityWebHttpRequest());
        }
    }
}

下篇文章 https://blog.csdn.net/wlqchengzhangji/article/details/118705159

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
UnityWebRequestUnity 引擎提供的一种用于发送网络请求的类,它支持多种协议,包括 HTTP、HTTPS、FTP、File 等。下面是一个简单的例子,演示如何使用 UnityWebRequest 发送一个 GET 请求: ```csharp IEnumerator GetRequest(string url) { using (UnityWebRequest webRequest = UnityWebRequest.Get(url)) { yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError) { Debug.LogError("Error: " + webRequest.error); } else { Debug.Log("Response: " + webRequest.downloadHandler.text); } } } ``` 这里使用了 IEnumerator 和 yield 关键字,因为 UnityWebRequest 是异步执行的,需要使用协程来处理。 使用 UnityWebRequest 发送 POST 请求也很简单,只需要将上面的 GetRequest 方法修改为: ```csharp IEnumerator PostRequest(string url, string data) { byte[] bodyRaw = Encoding.UTF8.GetBytes(data); using (UnityWebRequest webRequest = UnityWebRequest.Post(url, "POST")) { webRequest.uploadHandler = new UploadHandlerRaw(bodyRaw); webRequest.downloadHandler = new DownloadHandlerBuffer(); webRequest.SetRequestHeader("Content-Type", "application/json"); yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError) { Debug.LogError("Error: " + webRequest.error); } else { Debug.Log("Response: " + webRequest.downloadHandler.text); } } } ``` 这里使用了 UploadHandlerRaw 将请求体转换为 byte 数组,并设置了 Content-Type 为 application/json。同时使用 DownloadHandlerBuffer 接收服务器响应的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Data菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值