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;
/// <summary>
/// Http请求
/// </summary>
public class HTTPRequest
{
    private string url;
    private int timeout;
    private Action<HTTPResponse> callback;
    private HttpWebRequest request;
    private string method;
    private string contentType;
    private KeyValuePair<string, int> proxy;
    protected int range = -1;
    // post内容
    private StringBuilder postBuilder;
    /// <summary>
    /// 错误代码
    /// </summary>
    public const int ERR_EXCEPTION = -1;
    /// <summary>
    /// 构造函数, 构造GET请求
    /// </summary>
    /// <param name="url">url地址</param>
    /// <param name="timeout">超时时间</param>
    /// <param name="callback">回调函数</param>
    public HTTPRequest (string url, string method, int timeout, Action<HTTPResponse> callback)
    {
        this.url = url;
        this.timeout = timeout;
        this.callback = callback;
        this.method = method.ToUpper();
    }
    /// <summary>
    /// 设置Post内容
    /// </summary>
    /// <param name="data">内容</param>
    public void SetPostData(string data) {
        if (postBuilder == null) {
            postBuilder = new StringBuilder (data.Length);
        }
        if (postBuilder.Length > 0) {
            postBuilder.Append ("&");
        }
        postBuilder.Append (data);
    }
    /// <summary>
    /// 添加Post内容
    /// </summary>
    /// <param name="key">key值</param>
    /// <param name="value">value值</param>
    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));
    }
    /// <summary>
    /// 设置代理
    /// </summary>
    /// <param name="ip">ip地址</param>
    /// <param name="port">端口号</param>
    public void SetProxy(string ip, int port) {
        this.proxy = new KeyValuePair<string, int> (ip, port);
    }
    /// <summary>
    /// 设置ContentType
    /// </summary>
    /// <value>ContentType value</value>
    public string ContentType {
        set {
            this.contentType = value;
        }
    }
    /// <summary>
    /// 发动请求
    /// </summary>
    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 ();
            }
        }
    }
    /// <summary>
    /// 处理读取Response
    /// </summary>
    /// <param name="result">异步回到result</param>
    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 ();
            }
        }
    }
    /// <summary>
    /// 回调
    /// </summary>
    /// <param name="code">编码</param>
    /// <param name="content">内容</param>
    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);
        }
    }
    /// <summary>
    /// 回调
    /// </summary>
    /// <param name="code">编码</param>
    /// <param name="content">内容</param>
    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);
        }
    }
    /// <summary>
    /// 写Post内容
    /// </summary>
    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 ();
    }
    /// <summary>
    /// URLEncode
    /// </summary>
    /// <returns>encode value</returns>
    /// <param name="value">要encode的值</param>
    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;
/// <summary>
/// HTTP返回内容
/// </summary>
public class HTTPResponse
{
    // 状态码
    private int statusCode;
    // 响应字节
    private byte[] responseBytes;
    // 错误内容
    private string error;
    /// <summary>
    /// 默认构造函数
    /// </summary>
    public HTTPResponse ()
    {
    }
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="content">响应内容</param>
    public HTTPResponse (byte[] content)
    {
        this.responseBytes = content;
    }
    /// <summary>
    /// 获取响应内容
    /// </summary>
    /// <returns>响应文本内容</returns>
    public string GetResponseText() {
        if (null == this.responseBytes) {
            return null;
        }
        return Encoding.UTF8.GetString (this.responseBytes);
    }
    /// <summary>
    /// 将响应内容存储到文件
    /// </summary>
    /// <param name="fileName">文件名称</param>
    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 ();
    }
    /// <summary>
    /// 获取状态码
    /// </summary>
    /// <value>状态码</value>
    public int StatusCode {
        set { 
            this.statusCode = value;
        }
        get {
            return this.statusCode;
        }
    }
    /// <summary>
    /// 获取错误消息
    /// </summary>
    /// <value>错误消息</value>
    public string Error {
        set {
            this.error = value;
        }
        get {
            return this.error;
        }
    }
}

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

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

猜你喜欢

转载自blog.csdn.net/qq_35037137/article/details/88764979
今日推荐