Unity-Http协议请求下载系列2:HttpWebRequest封装

40 篇文章 3 订阅

上篇文章介绍了Http请求的接口封装,本篇具体介绍基于HttpWebRequest接口实现的资源请求下载。HttpWebRequestHelper实现完全重新请求下载和断点续传,并且是异步多线程执行的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.IO;
using System.Text;
using System;
using System.Threading;

/*
* Author:W
* .NET的网络请求下载接口
*/
namespace W.GameFramework.HotUpdate
{
	public class HttpWebRequestHelper : HttpHelper
	{
        private HttpWebRequest httpWebRequest = null;
        private HttpWebResponse httpWebResponse = null;
        private Thread requestThread = null;
        private FileStream fileStream = null;
        private Stream responseStream = 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);

            if (downloadType == DownloadType.New)
            {
                SendHttpRequestByNew();
            }
            else if (downloadType == DownloadType.Continue)
            {
                SendHttpRequestByContinue();
            }

        }

        #region 异步请求下载【完整重新下载】
        /// <summary>
        /// 请求下载:完整重新下载
        /// </summary>
        private void SendHttpRequestByNew()
        {
            try
            {
                httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
                httpWebRequest.Timeout = timeOut;
                httpWebRequest.Method = method;
                AsyncCallback asyncCallback = new AsyncCallback(OnResponseCallBack);
                httpWebRequest.BeginGetResponse(asyncCallback, null);
                //文件请求下载开始回调
                if (OnDownloadBeginHandler != null)
                    OnDownloadBeginHandler();
            }
            catch (Exception e)
            {
                //文件请求下载错误回调
                if (OnDownloadErrorHandler != null)
                    OnDownloadErrorHandler(e.Message);
                if (httpWebRequest != null)
                    httpWebRequest.Abort();
            }
        }

        /// <summary>
        /// 异步请求返回结果处理
        /// </summary>
        /// <param name="asyncResult"></param>
        private void OnResponseCallBack(IAsyncResult asyncResult)
        {
            try
            {
                httpWebResponse = httpWebRequest.EndGetResponse(asyncResult) as HttpWebResponse;

                //计算请求加载的文件总长度
                fileLength = httpWebResponse.ContentLength;

                if (httpWebResponse.StatusCode == HttpStatusCode.OK)
                {
                    //检查本地是否缓存请求下载文件,如果有则删除                    
                    if (File.Exists(path))
                        File.Delete(path);
                    fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);

                    //计算文件本地已加载的长度
                    fileCurLength = fileStream.Length;
                    progress = (float)fileCurLength / fileLength;

                    //请求内容Byte数据读取
                    responseStream = httpWebResponse.GetResponseStream();
                    byte[] readBuff = new byte[2048];

                    int len = -1;
                    while ((len = responseStream.Read(readBuff, 0, readBuff.Length)) > 0)
                    {
                        //停止请求下载
                        if (IsStop)
                        {
                            Clear();
                            return;
                        }

                        fileStream.Write(readBuff, 0, len);
                        fileCurLength += len;
                        progress = (float)fileCurLength / fileLength;
                    }

                    //文件请求下载完成回调
                    if (OnDownloadEndHandler != null)
                        OnDownloadEndHandler();
                }
                else
                {
                    //文件请求下载错误回调
                    if (OnDownloadErrorHandler != null)
                        OnDownloadErrorHandler(httpWebResponse.StatusDescription);
                }
            }
            catch (Exception e)
            {
                //文件请求下载错误回调
                if (OnDownloadErrorHandler != null)
                    OnDownloadErrorHandler(e.Message);               
            }
            finally
            {
                Clear();
            }
        }
        #endregion


        #region 开线程请求下载【断点续传下载】
        /// <summary>
        /// 请求下载 【断点续传下载时】
        /// </summary>
        private void SendHttpRequestByContinue()
        {
            requestThread = new Thread(AsyncSendHttpRequest);
            requestThread.IsBackground = false;
            requestThread.Start();
        }

        /// <summary>
        /// 多线程异步请求下载
        /// </summary>
        private void AsyncSendHttpRequest()
        {
            try
            {
                fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
                //计算请求下载文件本地已缓存的数据大小
                fileCurLength = fileStream.Length;
                //先发出请求,获取请求下载的文件大小信息
                httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
                httpWebRequest.Method = "HEAD";
                httpWebRequest.Timeout = timeOut;
                httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
                if (httpWebResponse.StatusCode == HttpStatusCode.OK)
                {
                    //计算请求下载文件总的大小
                    fileLength = httpWebResponse.ContentLength;
                    progress = (float)fileCurLength / fileLength;

                    if (OnDownloadBeginHandler != null)
                        OnDownloadBeginHandler();

                    //说明请求下载文件未完成下载,请继续接着下载
                    if (progress < 1f)
                    {
                        //设定文件写入流的开始写入位置
                        fileStream.Seek(fileCurLength, SeekOrigin.Begin);

                        httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
                        httpWebRequest.Method = method;
                        httpWebRequest.Timeout = timeOut;
                        //向请求声明下载文件下载开始位置
                        httpWebRequest.AddRange((int)fileCurLength);

                        //请求返回
                        httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
                        if (httpWebResponse.StatusCode == HttpStatusCode.OK
                            || httpWebResponse.StatusCode == HttpStatusCode.PartialContent)
                        {
                            responseStream = httpWebResponse.GetResponseStream();
                            byte[] readBuff = new byte[2048];
                            int len = -1;
                            while ((len = responseStream.Read(readBuff, 0, readBuff.Length)) > 0)
                            {
                                //停止请求下载
                                if (IsStop)
                                {
                                    Clear();
                                    return;
                                }

                                fileStream.Write(readBuff, 0, len);

                                fileCurLength += len;
                                progress = (float)fileCurLength / fileLength;
                            }
                           
                            if (OnDownloadEndHandler != null)
                                OnDownloadEndHandler();
                        }
                        else
                        {
                            if (OnDownloadErrorHandler != null)
                                OnDownloadErrorHandler(httpWebResponse.StatusDescription);
                        }                       
                    }
                    else
                    {
                        progress = 1f;
                        if (OnDownloadEndHandler != null)
                            OnDownloadEndHandler();
                    }                   
                }
                else
                {
                    if (OnDownloadErrorHandler != null)
                        OnDownloadErrorHandler(httpWebResponse.StatusDescription);
                }                
            }
            catch (Exception e)
            {
                if (OnDownloadErrorHandler != null)
                    OnDownloadErrorHandler(e.Message);               
            }
            finally
            {
                Clear();
            }
        }
        #endregion


        public override void Clear()
        {
            if (responseStream != null)
            {
                responseStream.Close();
                responseStream = null;
            }

            if (httpWebResponse != null)
            {               
                httpWebResponse.Close();
                httpWebResponse = null;
            }

            if (httpWebRequest != null)
            {
                httpWebRequest.Abort();
                httpWebRequest = null;
            }
               
            if (fileStream != null)
            {
                fileStream.Flush();
                fileStream.Close();
                fileStream = null;
            }

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

下篇文章链接https://blog.csdn.net/wlqchengzhangji/article/details/118704731

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如果你需要在 Unity WebGL 中从服务器接收这些数据并进行处理,可以使用以下代码: ```csharp using System; using UnityEngine.Networking; public class Example : MonoBehaviour { public string url; // 服务器地址 public string starttime = "2023-05-07 09:54:22"; public string endtime = "2023-06-07 09:54:22"; IEnumerator Start() { // 创建一个 UnityWebRequest 对象 UnityWebRequest request = UnityWebRequest.Get(url); // 发送请求并等待服务器响应 yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError) { // 请求失败,输出错误信息 Debug.Log(request.error); } else { // 请求成功,从响应数据中获取 starttime 和 endtime string responseText = request.downloadHandler.text; // 假设响应数据为 JSON 格式,可以使用 JsonUtility 来解析 ResponseData responseData = JsonUtility.FromJson<ResponseData>(responseText); starttime = responseData.starttime; endtime = responseData.endtime; // 将字符串类型的 starttime 和 endtime 转换为 DateTime 类型 DateTime startTime = DateTime.ParseExact(starttime, "yyyy-MM-dd HH:mm:ss", null); DateTime endTime = DateTime.ParseExact(endtime, "yyyy-MM-dd HH:mm:ss", null); // 计算时间差 TimeSpan duration = endTime - startTime; // 输出时间差 Debug.Log(duration); } } [Serializable] private class ResponseData { public string starttime; public string endtime; } } ``` 在这个示例中,我们使用 UnityWebRequest 来向服务器发送请求,并等待服务器的响应。如果请求失败,我们将会输出错误信息;如果请求成功,我们将会从响应数据中获取 starttime 和 endtime,并计算它们之间的时间差。需要注意的是,在这个示例中,我们假设响应数据为 JSON 格式,可以使用 `JsonUtility` 来解析。如果响应数据不是 JSON 格式,你需要使用其他方法来解析响应数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Data菌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值