Unity usa httpClient para comunicarse con el servidor, litJson analiza los datos y publica la plataforma webGl para usar la herramienta Newtonsoft.Json para informar errores.

1. Primero hable sobre la diferencia entre HttpWebRequest, WebClient y HttpClient

HttpWebRequest permite a los desarrolladores controlar varios aspectos del proceso de solicitud/respuesta, como tiempos de espera, cookies, encabezados, protocolos. Otro beneficio es que la clase HttpWebRequest no bloquea el subproceso de la interfaz de usuario. Por ejemplo, la interfaz de usuario de su aplicación no dejará de responder cuando descargue un archivo grande de un servidor API de respuesta lenta. HttpWebRequest generalmente se usa junto con WebResponse, uno para enviar solicitudes y otro para obtener datos. HttpWebRquest es de más bajo nivel y puede tener una comprensión intuitiva de todo el proceso de acceso, pero también es más complicado.

WebClient es una abstracción de alto nivel creada por HttpWebRequest para simplificar las tareas más comunes. Durante el uso, encontrará que carece de configuraciones básicas de encabezado y tiempo de espera, pero se pueden lograr heredando httpwebrequest. En términos relativos, WebClient es más simple que WebRequest, lo que equivale a encapsular los métodos de solicitud y respuesta, pero debe tenerse en cuenta que Webclient y WebRequest heredan clases diferentes y no existe una relación entre los dos en términos de herencia. El uso de WebClient puede ser más lento (unos pocos milisegundos) que el uso directo de HttpWebRequest, pero es más simple, reduce muchos detalles y la cantidad de código es relativamente pequeña.

HttpClient es una biblioteca de cliente HTTP introducida por .NET 4.5. Su espacio de nombres es System.Net.Http. Antes de .NET 4.5, podemos usar WebClient y HttpWebRequest para lograr el mismo propósito. HttpClient aprovecha los últimos patrones orientados a tareas, lo que facilita el manejo de solicitudes asincrónicas. Es adecuado para múltiples operaciones de solicitud. Generalmente, después de establecer el encabezado predeterminado, se pueden realizar solicitudes repetidas. Básicamente, cualquier solicitud HTTP se puede enviar con una instancia. HttpClient tiene un mecanismo de calentamiento y es relativamente lento cuando se accede por primera vez, por lo que no debe usar HttpClient y simplemente crear uno nuevo, debe usar un singleton u otros métodos para obtener una instancia de HttpClient

2. Soy unity2021.2.8 aquí, y lo he estudiado durante mucho tiempo, incluido el foso del análisis json

directamente en el código

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; }
}

Método de llamada Directo, por ejemplo, ResponseLogin es la estructura del análisis de datos devuelto, después de recibir la devolución de llamada, simplemente fuerce el tipo de objeto directamente

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

3. El problema del análisis json es diferente en diferentes plataformas

Además, puede usar este LitJson o Newtonsoft.Json para el análisis json. Puede descargar el dll y colocarlo directamente en el proyecto Activos-> Complementos. Si aún no puede encontrar la referencia en el código, haga clic derecho en el proyecto en vs Agregar -> Elemento existente, seleccione el dll

Pero el análisis de Newtonsoft, no se puede publicar en webGl, habrá errores, probablemente porque el método de implementación no es compatible con la reflexión en js, el error es este: plataformaNotSupportedException: la operación no es compatible con esta plataforma en System.Reflection.Emit.DynamicMethod . ..

Entonces es mejor usar LitJson para analizar

Supongo que te gusta

Origin blog.csdn.net/github_38633141/article/details/123137557
Recomendado
Clasificación