Unity发送HTTP请求和文件下载

Unity发送HTTP请求和文件下载

本类库封装基于ulua框架LuaFramework

1. 使用的类库

HttpWebRequest
HttpWebResponse
LuaFramework

2. 实现了哪些功能

  • 发送GET、POST请求
  • HTTP请求异步化
  • 支持Lua回调
  • 支持Host,采用Proxy的实现方式
  • 支持将HTTP请求内容保存为文件
  • HTTP下载文件,支持断电续传

3. HTTP实现思路

  • HTTPRequest 发起HTTP请求,异步回调返回HTTPResponse
    HTTPRequest源码
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;
using LuaFramework;
using UnityEngine;
/// 
/// Http请求
/// 
public class HTTPRequest
{
    private string url;
    private int timeout;
    private Action callback;
    private HttpWebRequest request;
    private string method;
    private string contentType;
    private KeyValuePair proxy;
    protected int range = -1;
    // post内容
    private StringBuilder postBuilder;
    /// 
    /// 错误代码
    /// 
    public const int ERR_EXCEPTION = -1;
    /// 
    /// 构造函数, 构造GET请求
    /// 
    /// url地址
    /// 超时时间
    /// 回调函数
    public HTTPRequest (string url, string method, int timeout, Action callback)
    {
        this.url = url;
        this.timeout = timeout;
        this.callback = callback;
        this.method = method.ToUpper();
    }
    /// 
    /// 设置Post内容
    /// 
    /// 内容
    public void SetPostData(string data) {
        if (postBuilder == null) {
            postBuilder = new StringBuilder (data.Length);
        }
        if (postBuilder.Length > 0) {
            postBuilder.Append ("&");
        }
        postBuilder.Append (data);
    }
    /// 
    /// 添加Post内容
    /// 
    /// key值
    /// value值
    public void AddPostData(string key, string value) {
        if (postBuilder == null) {
            postBuilder = new StringBuilder ();
        }
        if (postBuilder.Length > 0) {
            postBuilder.Append ("&");
        }
        postBuilder.Append (key).Append ("=").Append (UrlEncode (value));
    }
    /// 
    /// 设置代理
    /// 
    /// ip地址
    /// 端口号
    public void SetProxy(string ip, int port) {
        this.proxy = new KeyValuePair (ip, port);
    }
    /// 
    /// 设置ContentType
    /// 
    /// ContentType value
    public string ContentType {
        set {
            this.contentType = value;
        }
    }
    /// 
    /// 发动请求
    /// 
    public void Start() {
        Debug.Log ("Handle Http Request Start");
        this.request = WebRequest.Create (url) as HttpWebRequest;
        this.request.Timeout = timeout;
        this.request.Method = method;
        if (this.proxy.Key != null) {
            this.request.Proxy = new WebProxy(this.proxy.Key, this.proxy.Value);
        }
        if (this.contentType != null) {
            this.request.ContentType = this.contentType;
        }
        if (this.range != -1) {
            this.request.AddRange (this.range);
        }
        // POST写POST内容
        if (method.Equals ("POST")) {
            WritePostData ();
        }
        try {
            AsyncCallback callback = new AsyncCallback (OnResponse);
            this.request.BeginGetResponse (callback, null);
        } catch (Exception e) {
            CallBack (ERR_EXCEPTION, e.Message);
            if (request != null) {
                request.Abort ();
            }
        }
    }
    /// 
    /// 处理读取Response
    /// 
    /// 异步回到result
    protected void OnResponse(IAsyncResult result) {
        //Debug.Log ("Handle Http Response");
        HttpWebResponse response = null;
        try {
            // 获取Response
            response = request.EndGetResponse (result) as HttpWebResponse;
            if (response.StatusCode == HttpStatusCode.OK) {
                if ("HEAD".Equals(method)) {
                    // HEAD请求
                    long contentLength = response.ContentLength;
                    CallBack((int)response.StatusCode, contentLength + "");
                    return;
                }
                // 读取请求内容
                Stream responseStream = response.GetResponseStream();
                byte[] buff = new byte[2048];
                MemoryStream ms = new MemoryStream();
                int len = -1;
                while ((len = responseStream.Read(buff, 0, buff.Length)) > 0) {
                    ms.Write(buff, 0, len);
                }
                // 清理操作
                responseStream.Close();
                response.Close();
                request.Abort();
                // 调用回调
                CallBack ((int)response.StatusCode, ms.ToArray());
            } else {
                CallBack ((int)response.StatusCode, "");
            }
        } catch (Exception e) {
            CallBack (ERR_EXCEPTION, e.Message);
            if (request != null) {
                request.Abort ();
            }
            if (response != null) {
                response.Close ();
            }
        }
    }
    /// 
    /// 回调
    /// 
    /// 编码
    /// 内容
    private void CallBack(int code, string content) {
        Debug.LogFormat ("Handle Http Callback, code:{0}", code);
        if (callback != null) {
            HTTPResponse response = new HTTPResponse ();
            response.StatusCode = code;
            response.Error = content;
            callback (response);
        }
    }
    /// 
    /// 回调
    /// 
    /// 编码
    /// 内容
    private void CallBack(int code, byte[] content) {
        Debug.LogFormat ("Handle Http Callback, code:{0}", code);
        if (callback != null) {
            HTTPResponse response = new HTTPResponse (content);
            response.StatusCode = code;
            callback (response);
        }
    }
    /// 
    /// 写Post内容
    /// 
    private void WritePostData() {
        if (null == postBuilder || postBuilder.Length <= 0) {
            return;
        }
        byte[] bytes = Encoding.UTF8.GetBytes (postBuilder.ToString ());
        Stream stream = request.GetRequestStream ();
        stream.Write (bytes, 0, bytes.Length);
        stream.Close ();
    }
    /// 
    /// URLEncode
    /// 
    /// encode value
    /// 要encode的值
    private string UrlEncode(string value) {
        StringBuilder sb = new StringBuilder();
        byte[] byStr = System.Text.Encoding.UTF8.GetBytes(value);
        for (int i = 0; i < byStr.Length; i++)
        {
            sb.Append(@"%" + Convert.ToString(byStr[i], 16));
        }
        return (sb.ToString());
    }
}

HTTPResponse源码

using System;
using System.IO;
using System.Text;
using UnityEngine;
using LuaFramework;
/// 
/// HTTP返回内容
/// 
public class HTTPResponse
{
    // 状态码
    private int statusCode;
    // 响应字节
    private byte[] responseBytes;
    // 错误内容
    private string error;
    /// 
    /// 默认构造函数
    /// 
    public HTTPResponse ()
    {
    }
    /// 
    /// 构造函数
    /// 
    /// 响应内容
    public HTTPResponse (byte[] content)
    {
        this.responseBytes = content;
    }
    /// 
    /// 获取响应内容
    /// 
    /// 响应文本内容
    public string GetResponseText() {
        if (null == this.responseBytes) {
            return null;
        }
        return Encoding.UTF8.GetString (this.responseBytes);
    }
    /// 
    /// 将响应内容存储到文件
    /// 
    /// 文件名称
    public void SaveResponseToFile(string fileName) {
        if (null == this.responseBytes) {
            return;
        }
        // FIXME 路径跨平台问题
        string path = Path.Combine (Application.dataPath +"/StreamingAssets", fileName);
        FileStream fs = new FileStream (path, FileMode.Create);
        BinaryWriter writer = new BinaryWriter (fs);
        writer.Write (this.responseBytes);
        writer.Flush ();
        writer.Close ();
        fs.Close ();
    }
    /// 
    /// 获取状态码
    /// 
    /// 状态码
    public int StatusCode {
        set { 
            this.statusCode = value;
        }
        get {
            return this.statusCode;
        }
    }
    /// 
    /// 获取错误消息
    /// 
    /// 错误消息
    public string Error {
        set {
            this.error = value;
        }
        get {
            return this.error;
        }
    }
}

更多unity2018的功能介绍请到paws3d爪爪学院查找。链接https://www.paws3d.com/learn/,也可以加入unity学习讨论群935714213

近期更有资深开发人士直播分享unity开发经验,详情请进入官网或加入QQ群了解

你可能感兴趣的:(unity2018)