Unity游戏开发-客户端Http下载
本篇主要分享基于.Net实现⼀个客户端Http下载模块。
Http下载这块和服务器也有⼀定的联系,关于服务器Http下载模块的实现后⾯有时间再贴出来吧,主要是和客户端约定⼀下HttpPost参数的解析⽅式。
Http下载这块主要还是基于.Net库⾥⾯的HttpWebRequest类去实现的。
这⾥主要是封装了⼀些数据结构⽤于⽀持下载的显⽰,封装了多线程的处理避免Http请求造成线程的阻塞,封装了⽂件流的下载保存和md5校验。
⼀个分为两个部分:
HttpDownLoad-开启线程,创建下载任务,更新下载状态
HttpDownPack-Http下载任务的数据结构定义
HttpDownPack
public class HttpDownPack
{
// ⽹络错误重试次数
单人开发选ue4还是unitypublic int tryNum;
// 服务器http地址
public string url;
// post请求参数
public byte[] param;
// 下载后本地⽂件保存路径
public string localFile;
// ⽂件的md5
public string md5;
/
/ 请求超时时间
public int timeOut = 5000;
// 下载状态
public HttpDownState state;
// 当前下载的⼤⼩
public int downSize;
}
public enum HttpDownState
{
Ready = 0,
DownLoading = 1,
Complete = 2,
Md5Failed = 3,
Error = 4
}
其中param是我们post请求需要构建的参数。
整体的设计师param的前四个字节构成⼀个int类型,其代表的是我们给服务器推送的协议号来表⽰我们需要做什么样的业务。
这⾥将2表⽰为请求下载⽂件。
param的后续字节为当前请求类型约定的数据结构。
这⾥下载约定的数据结构为
// 下载任务数据结构
public class DatHttpDown
{
// 下载路径
public string path;
// 当前下载的字节数
public long startByte;
}
最终我们将协议类型2、下载数据结构转换为json字符串再转换为⼆进制⼀起写⼊param中构成⼀条完整的请求参数。
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter bw = new BinaryWriter(ms))
{
//......
//请求下载
bw.Write(2);
//构建下载参数
DatHttpDown datHttpDown = new DatHttpDown();
datHttpDown.path = "xxxx/xxx";
datHttpDown.startByte = 0;
bw.Write(System.Text.Encoding.UTF8.GetBytes(LitJson.JsonMapper.ToJson(datHttpDown)));
downPack.param = ms.ToArray();
_httpDownLoad.AddHttpReq(downPack);
}
}
HttpDownLoad
⾸先定义了⼀个下载队列,⾥⾯存放的就是HttpDownPack。
提供⼀个AddHttpReq的⽅法,外部调⽤该⽅法将构建好的HttpDownPack存⼊队列中。
开启⼀个线程不停的从队列中获取HttpDownPack并执⾏下载任务。
下载的过程中不断的更新HttpDownPack中的数据,以便业务层可以获取到下载的进度。
public class HttpDownLoad
{
private Thread mSendTask;
private bool mAlive;
private string HTTP_DOWN_PATH;
private BlockQueue<HttpDownPack> mDownList = new BlockQueue<HttpDownPack>(50);
public void Init()
{
mSendTask = new Thread(DownTask);
mSendTask.IsBackground = true;
mSendTask.Start();
mAlive = true;
HTTP_DOWN_PATH = PathMgr.instance.DownTmpPath;
if (!Directory.Exists(HTTP_DOWN_PATH))
{
Directory.CreateDirectory(HTTP_DOWN_PATH);
}
}
public void AddHttpReq(HttpDownPack pack)
{
mDownList.Enqueue(pack);
}
private void DownTask()
{
while (mAlive)
{
var downPack = mDownList.Dequeue();
Down(downPack);
}
}
private void Down(HttpDownPack pack)
{
HttpWebRequest req;
HttpWebResponse res = null;
req = (HttpWebRequest)WebRequest.Create(new Uri(pack.url));
req.Method = "POST";
req.Timeout = pack.timeOut;
try
{
if (pack.param != null)
{
Stream stream = req.GetRequestStream();
stream.Write(pack.param, 0, pack.param.Length);
stream.Close();
}
res = (HttpWebResponse)req.GetResponse();
string tmpFilePath = HTTP_DOWN_PATH + "/" + pack.md5;
FileTool.DeleteFile(tmpFilePath);
using (FileStream fs = new FileStream(tmpFilePath, FileMode.OpenOrCreate))            {
using (Stream resStream = res.GetResponseStream())
{
byte[] buffer = new byte[1024];
// 下载中
pack.state = HttpDownState.DownLoading;
int size = resStream.Read(buffer, 0, 1024);
while (size > 0)
{
fs.Write(buffer, 0, size);
pack.downSize += size;
size = resStream.Read(buffer, 0, 1024);
}
resStream.Close();
fs.Close();
}
}
FileTool.DeleteFile(pack.localFile);
File.Move(tmpFilePath, pack.localFile);
if (MD5.GetMD5FromFile(pack.localFile).Equals(pack.md5))
{
pack.state = HttpDownState.Complete;
FDebug.Log("⽂件下载成功!"+ pack.localFile);
}
else
{
pack.state = HttpDownState.Md5Failed;
pack.state = HttpDownState.Md5Failed;
FDebug.Log("⽂件md5校验失败" + pack.localFile);            }
}
catch (WebException ex)
{
FDebug.Log("⽂件下载出错!" + pack.localFile);
req.Abort();
/
/ 下载错误
pack.state = HttpDownState.Error;
FDebug.Log(ex.Message);
}
finally
{
if (res != null)
{
res.Close();
}
}
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。