1. Сначала поговорим о разнице между HttpWebRequest, WebClient и HttpClient.
HttpWebRequest позволяет разработчикам контролировать различные аспекты процесса запроса/ответа, такие как тайм-ауты, файлы cookie, заголовки, протоколы. Еще одно преимущество заключается в том, что класс HttpWebRequest не блокирует поток пользовательского интерфейса. Например, пользовательский интерфейс вашего приложения не перестанет отвечать, когда вы загрузите большой файл с медленно реагирующего сервера API. HttpWebRequest обычно используется вместе с WebResponse, один для отправки запросов и один для получения данных. HttpWebRquest более низкоуровневый и может интуитивно понимать весь процесс доступа, но и более сложный.
WebClient — это абстракция более высокого уровня, созданная HttpWebRequest для упрощения наиболее распространенных задач.Во время использования вы обнаружите, что в нем отсутствуют базовые настройки заголовка и времени ожидания, но этого можно добиться, унаследовав httpwebrequest. Условно говоря, WebClient проще, чем WebRequest, что эквивалентно инкапсуляции методов запроса и ответа, но следует отметить, что Webclient и WebRequest наследуют разные классы, и между ними нет никакой связи с точки зрения наследования. Использование WebClient может быть медленнее (около нескольких миллисекунд), чем непосредственное использование HttpWebRequest, но оно проще, сокращает количество деталей, а объем кода относительно невелик.
HttpClient — это клиентская библиотека HTTP, представленная в .NET4.5.Ее пространство имен — System.Net.Http.До .NET 4.5 мы могли использовать WebClient и HttpWebRequest для достижения той же цели. HttpClient использует новейшие шаблоны, ориентированные на задачи, что упрощает обработку асинхронных запросов. Он подходит для операций с несколькими запросами. Как правило, после установки заголовка по умолчанию можно делать повторные запросы. По сути, любой HTTP-запрос может быть отправлен с одним экземпляром. HttpClient имеет механизм прогрева, и он относительно медленный при доступе в первый раз, поэтому вам не следует использовать HttpClient, а просто создать новый, вы должны использовать синглтон или другие методы для получения экземпляра 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; }
}
Вызов метода Direct, например, ResponseLogin - это структура возвращаемого анализа данных, после получения обратного вызова просто принудительно введите тип объекта напрямую
HttpHelp.Instance.SendMsg<ResponseLogin>(HttpCode.Email_Login, data, (obj)=> { данные ResponseLogin = obj as ResponseLogin; });
3. Проблема парсинга json отличается на разных платформах
Кроме того, вы можете использовать этот LitJson или Newtonsoft.Json для анализа json.Вы можете скачать dll и поместить его прямо в проекте Assets->Plugins.Если вы все еще не можете найти ссылку в коде, щелкните правой кнопкой мыши на проект в vs Add -> Existing item, выбираем dll
А вот анализ Newtonsoft, не могу публиковать в webGl, будут ошибки, наверное из-за того, что метод реализации не поддерживает отражение в js, ошибка вот такая: platformNotSupportedException : Операция не поддерживается на этой платформе. at System.Reflection.Emit.DynamicMethod ...
Так что лучше использовать LitJson для разбора