Unity3d HTTP 通讯

HTTP 请求

前言
HTTP 请求的过程这里不再赘述,有兴趣的小伙伴可以自己搜索。
请求方式有Get和Post方式,Get即请求指定的页面信息,Post是向指定资源提交数据进行处理请求。
我们使用中会用到同步请求和异步请求,以下分别介绍。

1、同步请求
经常使用的一种http请求,请求后会直接得到结果,使用简单。但是请求连接无法访问的时候会卡死整个线进,体验很差。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;

/// Http 同步请求
public class HttpSynRequest
{
    /// <summary>
    /// 获取URL数据
    /// </summary>
    public string Content { get; private set; }

    /// <summary>
    /// 请求错误
    /// </summary>
    public string ErrorMsg { get; private set; }

    /// <summary>
    /// url 请求地址
    /// </summary>
    private string urlRequest;

    /// <summary>
    /// 重试次数
    /// </summary>
    private int tryTimesLimit;

    /// <summary>
    /// http请求方法 get post
    /// </summary>
    private string methodRequest;

    /// <summary>
    /// http请求参数
    /// </summary>
    private string dataRequest;

    /// <summary>
    /// HttpWebRequest
    /// </summary>
    private HttpWebRequest webRequest;

    /// <summary>
    /// HttpWebRequest
    /// </summary>
    private HttpWebResponse webResponse;

    /// <summary>
    /// 构造函数
    /// </summary>
    public HttpSynRequest(string url, string method, string param = "", int times = 0)
    {
        urlRequest = url;
        methodRequest = method;
        tryTimesLimit = times;
        dataRequest = param;
    }

    /// <summary>
    /// 开始请求
    /// </summary>
    public void Start()
    {
        if (string.IsNullOrEmpty(urlRequest))
        {
            ErrorMsg = "url is empty";
            return;
        }

        HttpMethodRequest();
    }

    /// <summary>
    /// http 请求方式
    /// </summary>
    private void HttpMethodRequest()
    {
        if (methodRequest.CompareTo("Post") == 0)
            HttpRequestPost();
        else
            HttpRequestGet();
    }

    /// <summary>
    /// 创建WebRequest 
    /// </summary>
    public HttpWebRequest CreateRequest(string url)
    {
        //https,并且设置了SSL,我们在访问程序时可能远程证书无效
        if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
        {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.ProtocolVersion = HttpVersion.Version11;
            return request;
        }
        else
        {
            return (HttpWebRequest)HttpWebRequest.Create(url);
        }
    }

    /// <summary>
    /// 创建WebRequest 
    /// </summary>
    private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
    {
        return true;
    }

    /// <summary>
    /// 通过远程证书验证,总是返回true
    /// </summary>
    private void HttpRequestGet()
    {
        try
        {
            string url = urlRequest;
            if (!string.IsNullOrEmpty(dataRequest))
                url = string.Format("{0}?p={1}", urlRequest, dataRequest);

            webRequest = CreateRequest(url);
            webResponse = (HttpWebResponse)webRequest.GetResponse();
            using (var s = webResponse.GetResponseStream())
            {
                StreamReader sr = new StreamReader(s);
                Content = sr.ReadToEnd();
                sr.Close();
                s.Close();
            }
            ErrorMsg = string.Empty;
        }
        catch (System.Exception ex)
        {
            ErrorMsg = ex.Message;
        }
        finally
        {
            Abort();
        }

        TrtRequestAgain();
    }

    /// <summary>
    /// http post 请求
    /// </summary>
    private void HttpRequestPost()
    {
        string md5 = GetMd5(dataRequest);
        dataRequest += "&sign=" + md5;
          
        try
        {
            HttpWebRequest request = CreateRequest(urlRequest);
            request = WebRequest.Create(urlRequest) as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            byte[] data = Encoding.UTF8.GetBytes(dataRequest);
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }
            webResponse = request.GetResponse() as HttpWebResponse;
            using (var s = webResponse.GetResponseStream())
            {
                StreamReader sr = new StreamReader(s);
                Content = sr.ReadToEnd();
                sr.Close();
                s.Close();
            }
            ErrorMsg = string.Empty;
        }
        catch (System.Exception ex)
        {
            ErrorMsg = ex.Message;
        }

        finally
        {
            Abort();
        }

        TrtRequestAgain();
    }

    /// <summary>
    /// 终止
    /// </summary>
    private void Abort()
    {
        if (webResponse != null)
        {
            webResponse.Close();
            webResponse = null;
        }
        if (webRequest != null)
        {
            webRequest.Abort();
            webRequest = null;
        }
    }

    /// <summary>
    /// http请求如果失败,再次尝试
    /// </summary>
    private void TrtRequestAgain()
    {
        if (string.IsNullOrEmpty(ErrorMsg))
        {
            return;
        }

        if (tryTimesLimit > 0)
        {
            tryTimesLimit--;
            HttpMethodRequest();
        }
    }

    /// <summary>
    /// 获得MD5
    /// </summary>
    private string GetMd5(string input)
    {
        MD5 md5Hash = MD5.Create();
        byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

        StringBuilder sBuilder = new StringBuilder();

        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));
        }

        return sBuilder.ToString();
    }
}

调用示例

	HttpSynRequest request = new HttpSynRequest("https://www.baidu.com/", "Get");//Get方式
    request.Start();
    string err = request.ErrorMsg;
    string content = request.Content;

2、异步请求
异步请求会单独开一个线程进行http请求,不会影响主线程运行,但是不能实时拿到结果,需要监听请求的完成。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;

/// Http 异步请求
public class HttpAsynRequest
{
    /// <summary>
    /// 是否完成
    /// </summary>
    public bool IsDone { get; private set; }

    /// <summary>
    /// 获取URL数据
    /// </summary>
    public string Content { get; private set; }

    /// <summary>
    /// 请求错误
    /// </summary>
    public string ErrorMsg { get; private set; }

    /// <summary>
    /// url 请求地址
    /// </summary>
    private string urlRequest;

    /// <summary>
    /// 重试次数
    /// </summary>
    private int tryTimesLimit;

    /// <summary>
    /// http请求方法 get post
    /// </summary>
    private string methodRequest;

    /// <summary>
    /// http请求参数
    /// </summary>
    private string dataRequest;

    /// <summary>
    /// HttpWebRequest
    /// </summary>
    private HttpWebRequest webRequest;

    /// <summary>
    /// HttpWebRequest
    /// </summary>
    private HttpWebResponse webResponse;

    /// <summary>
    /// 异步获取
    /// </summary>
    private Thread thread_;

    /// <summary>
    /// 构造函数
    /// </summary>
    public HttpAsynRequest(string url, string method, string param = "", int times = 0)
    {
        IsDone = false;
        urlRequest = url;
        methodRequest = method;
        tryTimesLimit = times;
        dataRequest = param;
    }

    /// <summary>
    /// 开始校验
    /// </summary>
    public void Start()
    {
        if (string.IsNullOrEmpty(urlRequest))
        {

            ErrorMsg = "url is empty";
            return;
        }

        thread_ = new Thread(new ThreadStart(HttpMethodRequest));
        thread_.Start();
    }

    /// <summary>
    /// http 请求方式
    /// </summary>
    private void HttpMethodRequest()
    {
        if (methodRequest.CompareTo("Post") == 0)
            HttpRequestPost();
        else
            HttpRequestGet();
    }

    /// <summary>
    /// 创建WebRequest 
    /// </summary>
    public HttpWebRequest CreateRequest(string url)
    {
        //https,并且设置了SSL,我们在访问程序时可能远程证书无效
        if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
        {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.ProtocolVersion = HttpVersion.Version11;
            return request;
        }
        else
        {
            return (HttpWebRequest)HttpWebRequest.Create(url);
        }
    }

    /// <summary>
    /// 创建WebRequest 
    /// </summary>
    private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
    {
        return true;
    }

    /// <summary>
    /// http get 请求
    /// </summary>
    private void HttpRequestGet()
    {
        try
        {
            string url = urlRequest;
            if (!string.IsNullOrEmpty(dataRequest))
                url = string.Format("{0}?p={1}", urlRequest, dataRequest);

            webRequest = CreateRequest(url);
            webResponse = (HttpWebResponse)webRequest.GetResponse();
            using (var s = webResponse.GetResponseStream())
            {
                StreamReader sr = new StreamReader(s);
                Content = sr.ReadToEnd();
                sr.Close();
                s.Close();
            }
            ErrorMsg = string.Empty;
        }
        catch (System.Exception ex)
        {
            ErrorMsg = ex.Message;
        }
        finally
        {
            Abort();
        }

        TrtRequestAgain();
    }

    /// <summary>
    /// http post 请求
    /// </summary>
    private void HttpRequestPost()
    {
        string md5 = GetMd5(dataRequest);
        dataRequest += "&sign=" + md5;
        try
        {
            HttpWebRequest request = CreateRequest(urlRequest);
            request = WebRequest.Create(urlRequest) as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            byte[] data = Encoding.UTF8.GetBytes(dataRequest);
            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }
            webResponse = request.GetResponse() as HttpWebResponse;
            using (var s = webResponse.GetResponseStream())
            {
                StreamReader sr = new StreamReader(s);
                Content = sr.ReadToEnd();
                sr.Close();
                s.Close();
            }
            ErrorMsg = string.Empty;

        }
        catch (System.Exception ex)
        {
            ErrorMsg = ex.Message;
        }

        finally
        {
            Abort();
        }

        TrtRequestAgain();
    }

    /// <summary>
    /// 终止
    /// </summary>
    public void Abort()
    {
        if (webResponse != null)
        {
            webResponse.Close();
            webResponse = null;
        }
        if (webRequest != null)
        {
            webRequest.Abort();
            webRequest = null;
        }
    }

    /// <summary>
    /// http请求如果失败,再次尝试
    /// </summary>
    private void TrtRequestAgain()
    {
        if (string.IsNullOrEmpty(ErrorMsg))
        {
            IsDone = true;
            return;
        }

        if (tryTimesLimit > 0)
        {
            tryTimesLimit--;
            HttpMethodRequest();
        }
        else
            IsDone = true;
    }

    /// <summary>
    /// 获得MD5
    /// </summary>
    private string GetMd5(string input)
    {
        MD5 md5Hash = MD5.Create();
        byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

        StringBuilder sBuilder = new StringBuilder();

        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));
        }

        return sBuilder.ToString();
    }
}

获得请求结果常用的两种方式:

  • 在请求类中创建一个协成检测IsDone是否完成,完成后获得结果
  • HttpAsynRequest类中添加回调函数,完成回调。注意调用回调函数时,最好在主线程,否者有些操作不能放在回调里。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值