1.先说说HttpWebRequest、WebClient、HttpClient的区别

HttpWebRequest可以让开发者控制请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols。另一个好处是HttpWebRequest类不会阻塞UI线程。例如,当您从响应很慢的API服务器下载大文件时,您的应用程序的UI不会停止响应。HttpWebRequest通常和WebResponse一起使用,一个发送请求,一个获取数据。HttpWebRquest更为底层一些,能够对整个访问过程有个直观的认识,但同时也更加复杂一些。

WebClient是一种更高级别的抽象,是HttpWebRequest为了简化最常见任务而创建的,使用过程中你会发现他缺少基本的header,timeoust的设置,不过这些可以通过继承httpwebrequest来实现。相对来说,WebClient比WebRequest更加简单,它相当于封装了request和response方法,不过需要说明的是,Webclient和WebRequest继承的是不同类,两者在继承上没有任何关系。使用WebClient可能比HttpWebRequest直接使用更慢(大约几毫秒),但却更为简单,减少了很多细节,代码量也比较少。

HttpClient是.NET4.5引入的一个HTTP客户端库,其命名空间为 System.Net.Http ,.NET 4.5之前我们可能使用WebClient和HttpWebRequest来达到相同目的。HttpClient利用了最新的面向任务模式,使得处理异步请求非常容易。它适合用于多次请求操作,一般设置好默认头部后,可以进行重复多次的请求,基本上用一个实例可以提交任何的HTTP请求。HttpClient有预热机制,第一次进行访问时比较慢,所以不应该用到HttpClient就new一个出来,应该使用单例或其他方式获取HttpClient的实例

2.我这里是unity2021.2.8,研究了半天,包括json解析的坑

直接上代码

using UnityEngine;
using System.Net.Http;
using System;
using System.Threading.Tasks;
using LitJson;
// TSingleton是单例继承
public class HttpHelp : TSingleton<HttpHelp>
{
    HttpClient m_client = null;

    private string m_url = GameConfig.Url;

    public HttpHelp()
    {
        m_client = new HttpClient();
        m_client.MaxResponseContentBufferSize = 256000;// 最大返回的字节数
        m_client.Timeout = TimeSpan.FromMilliseconds(15000);// 超时时间
        // json解析的格式化添加
        LitJson.JsonMapper.RegisterImporter<long, int>((long input) => { return (int)input; });
        LitJson.JsonMapper.RegisterImporter<int, long>((int input) => { return (long)(input); });
    }
    // 回调方法
    public delegate void OnNetBack(object eventObj);
    public string Get(string url)
    {
        try
        {
            var responseString = m_client.GetStringAsync(url);
            return responseString.Result;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    public string Post(string url, string strJson)//post同步请求方法
    {
        try
        {
            HttpContent content = new StringContent(strJson);
            content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
            //client.DefaultRequestHeaders.Connection.Add("keep-alive");
            //由HttpClient发出Post请求
            Task<HttpResponseMessage> res = m_client.PostAsync(url, content);
            if (res.Result.StatusCode == System.Net.HttpStatusCode.OK)
            {
                string str = res.Result.Content.ReadAsStringAsync().Result;
                return str;
            }
            else
            {
                if (res.Result.StatusCode == System.Net.HttpStatusCode.RequestTimeout)
                {// 请求超时
                    UIManager.Instance.ShowTips("request time out!");
                    Debug.LogWarning("request time out !");
                }
                return null;
            }
        }
        catch (Exception ex)
        {
            Debug.LogException(ex);
            return null;
        }
    }

    public async Task<string> PostAsync(string url, string strJson)//post异步请求方法
    {
        try
        {
            HttpContent content = new StringContent(strJson);
            content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
            //由HttpClient发出异步Post请求
            HttpResponseMessage res = await m_client.PostAsync(url, content);
            if (res.StatusCode == System.Net.HttpStatusCode.OK)
            {
                string str = res.Content.ReadAsStringAsync().Result;
                return str;
            }
            else
            {
                if (res.StatusCode == System.Net.HttpStatusCode.RequestTimeout)
                {// 请求超时
                    UIManager.Instance.ShowTips("request time out!");
                    Debug.LogWarning("request time out !");
                }
                return null;
            }
        }
        catch (Exception ex)
        {
            Debug.LogException(ex);
            return null;
        }
    }

    public async void SendMsg<T>(int cmd, object param, OnNetBack callback)
    {
        
        RequestBaseData bas = new RequestBaseData();// 请求的数据结构体
        bas.setMessage(cmd, JsonMapper.ToJson(param));// 设置命令code和数据
        var jsonContent = new StringContent(JsonMapper.ToJson(bas));// 吧结构体数据stringJson
// 设置数据格式
        jsonContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");

        string res = await this.PostAsync(m_url, JsonMapper.ToJson(bas));
        if (res == null)
        {// 关闭菊花
            UIManager.Instance.ShowLoading(false);
            return;
        }
       // 吧返回的json数据解析成结构体
        ResponseBaseData data = JsonMapper.ToObject<ResponseBaseData>(@res);
        if (data.errorCode != 0)
        {
           // 服务器返回的错误码提示
            string reason = "request error status: "+m_url + cmd;
            Debug.LogError(reason);
            UIManager.Instance.ShowTips(data.errorCode.ToString());
        }
        else
        {
           
            if (data.sysMessage != null)
            {// 同步用户/心跳数据
                if (callback != null) callback(data.sysMessage);
            }
            else
            {
                // 格式化类型数据
                T t = JsonMapper.ToObject<T>(data.message);
                if (callback != null) callback(t);
            }
        }
        UIManager.Instance.ShowLoading(false);
    }

    public void SetUrl(string ip, int port)
    {
        m_url = @"http://" + ip + ":" + port;
    }
}
[Serializable]
// 请求数据
public class RequestBaseData
{
    public int code;
    public int eId = 0;
    public int isCheck = 0;
    public string message;
    public string playerId;
    public int pwd = 0;
    public string sessionKey;
    public int version = 266;
    public void setMessage(int code1, string message1)
    {
        message = message1;
        code = code1;
    }
}


// 返回数据
[Serializable]
public class ResponseBaseData
{
    public string code { get; set; }
    public int errorCode { get; set; }
    public string execution { get; set; }
    public string message { get; set; }
    public SysMessage sysMessage { get; set; }
    public string time { get; set; }
}

调用方式 直接,比如ResponseLogin是返回后的数据解析的结构,收到回调后 直接把object类型强转就可以了

 HttpHelp.Instance.SendMsg<ResponseLogin>(HttpCode.Email_Login, data, (obj)=> {
                ResponseLogin data = obj as ResponseLogin;
            });

3.json解析的问题,在不同平台

另外json解析  可以使用这个LitJson,也可以使用Newtonsoft.Json,都是下载好dll,直接放到项目Assets->Plugins下就可以,如果代码中引用还是找不到,那就在vs中选中项目右键 添加->现有项,选中那个dll就可以

但是Newtonsoft解析,不能发布到webGl,会有错误,大概原因估计是实现的方式在js中不支持反射,错误是这样 :platformNotSupportedException: Operation is not supported on this platform.   at System.Reflection.Emit.DynamicMethod...

所以最好使用LitJson去解析

GitHub 加速计划 / js / json
18
5
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:2 个月前 )
960b763e 5 个月前
8c391e04 8 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐