Unity UnityWebRequest封装类
简化api调用流程,非常奈斯。
RestWebClient.cs
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;namespace MYTOOL.RestClient
{/// <summary>/// UnityWebRequest封装类/// </summary>public class RestWebClient{private readonly MonoBehaviour executer;public RestWebClient(MonoBehaviour executer){if (executer == null) throw new ArgumentNullException();this.executer = executer;}#region >> GETpublic Coroutine Get(string url, Request req){if (req == null) throw new ArgumentNullException();return executer.StartCoroutine(InnerGet(url, req));}#endregion#region >> PUTpublic Coroutine Put(string url, Request req){if (req == null) throw new ArgumentNullException();return executer.StartCoroutine(InnerPut(url, req));}#endregion#region >> POSTpublic Coroutine Post(string url, Request req){if (req == null) throw new ArgumentNullException();return executer.StartCoroutine(InnerPost(url, req));}public Coroutine PostForm(string url, WWWForm formData, Request req){if (req == null) throw new ArgumentNullException();return executer.StartCoroutine(InnerPostForm(url, formData, req));}#endregion#region >> DELETEpublic Coroutine Delete(string url, Request req){if (req == null) throw new ArgumentNullException();return executer.StartCoroutine(InnerDelete(url, req));}#endregionprivate IEnumerator InnerGet(string url, Request req){req.OnBegin?.Invoke();ushort retryCount = req.RetryCount;do{using UnityWebRequest webRequest = UnityWebRequest.Get(url);InitUnityWebRequest(webRequest, req);yield return webRequest.SendWebRequest();bool isSuccess = webRequest.result == UnityWebRequest.Result.Success;if (isSuccess || retryCount == 0){if (DebugMode) LogInfo("GET", webRequest.responseCode, isSuccess, webRequest.url);req.Invoke(isSuccess, webRequest.responseCode, webRequest.downloadHandler.data, webRequest.error);yield break;}if (req.RetryInterval > 0){yield return new WaitForSeconds(req.RetryInterval);}} while (retryCount-- > 0);}private IEnumerator InnerPut(string url, Request req){req.OnBegin?.Invoke();ushort retryCount = req.RetryCount;do{using UnityWebRequest webRequest = UnityWebRequest.Put(url, req.BodyData);InitUnityWebRequest(webRequest, req);yield return webRequest.SendWebRequest();bool isSuccess = webRequest.result == UnityWebRequest.Result.Success;if (isSuccess || retryCount == 0){if (DebugMode) LogInfo("PUT", webRequest.responseCode, isSuccess, webRequest.url);req.Invoke(isSuccess, webRequest.responseCode, webRequest.downloadHandler.data, webRequest.error);yield break;}if (req.RetryInterval > 0){yield return new WaitForSeconds(req.RetryInterval);}} while (retryCount-- > 0);}private IEnumerator InnerPost(string url, Request req){req.OnBegin?.Invoke();ushort retryCount = req.RetryCount;do{using UnityWebRequest webRequest = UnityWebRequest.Post(url, req.BodyData);InitUnityWebRequest(webRequest, req);yield return webRequest.SendWebRequest();bool isSuccess = webRequest.result == UnityWebRequest.Result.Success;if (isSuccess || retryCount == 0){if (DebugMode) LogInfo("POST", webRequest.responseCode, isSuccess, webRequest.url);req.Invoke(isSuccess, webRequest.responseCode, webRequest.downloadHandler.data, webRequest.error);yield break;}if (req.RetryInterval > 0){yield return new WaitForSeconds(req.RetryInterval);}} while (retryCount-- > 0);}private IEnumerator InnerPostForm(string url, WWWForm formData, Request req){req.OnBegin?.Invoke();ushort retryCount = req.RetryCount;do{using UnityWebRequest webRequest = UnityWebRequest.Post(url, formData);InitUnityWebRequest(webRequest, req);yield return webRequest.SendWebRequest();bool isSuccess = webRequest.result == UnityWebRequest.Result.Success;if (isSuccess || retryCount == 0){if (DebugMode) LogInfo("POST", webRequest.responseCode, isSuccess, webRequest.url);req.Invoke(isSuccess, webRequest.responseCode, webRequest.downloadHandler.data, webRequest.error);yield break;}if (req.RetryInterval > 0){yield return new WaitForSeconds(req.RetryInterval);}} while (retryCount-- > 0);}private IEnumerator InnerDelete(string url, Request req){req.OnBegin?.Invoke();ushort retryCount = req.RetryCount;do{using UnityWebRequest webRequest = UnityWebRequest.Delete(url);webRequest.downloadHandler = new DownloadHandlerBuffer();InitUnityWebRequest(webRequest, req);yield return webRequest.SendWebRequest();bool isSuccess = webRequest.result == UnityWebRequest.Result.Success;if (isSuccess || retryCount == 0){if (DebugMode) LogInfo("DELETE", webRequest.responseCode, isSuccess, webRequest.url);req.Invoke(isSuccess, webRequest.responseCode, webRequest.downloadHandler.data, webRequest.error);yield break;}if (req.RetryInterval > 0){yield return new WaitForSeconds(req.RetryInterval);}} while (retryCount-- > 0);}private void InitUnityWebRequest(UnityWebRequest webRequest, Request req){webRequest.timeout = req.Timeout;if (webRequest.uploadHandler != null && string.IsNullOrEmpty(req.ContentType) == false){webRequest.uploadHandler.contentType = req.ContentType;}var queryString = req.GetQueryString();if (string.IsNullOrEmpty(queryString) == false){if (webRequest.url.EndsWith('?')){webRequest.url += queryString;}else{webRequest.url += $"?{queryString}";}}var headers = req.GetHeaders();foreach (var header in headers){webRequest.SetRequestHeader(header.Key, header.Value);}}public static bool DebugMode = true;private static void LogInfo(string method, long code, bool success, string info){string str = success ? $"<color=green>{info}</color>" : $"<color=red>{info}</color>";Debug.Log($"[{method}] [{code}] => {str}");}}
}
Request.cs
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;namespace MYTOOL.RestClient
{public class Request{public const string APPLICATION_JSON = "application/json";/// <summary>/// 超时时间/// </summary>public int Timeout { get; private set; }/// <summary>/// 重试次数/// </summary>public ushort RetryCount { get; private set; }/// <summary>/// 重试间隔(秒)/// </summary>public float RetryInterval { get; private set; }/// <summary>/// 内容/// </summary>public string BodyData { get; private set; }/// <summary>/// 内容类型/// </summary>public string ContentType { get; private set; }/// <summary>/// 请求是否完成/// </summary>public bool IsDone { get; private set; }/// <summary>/// 请求开始前的回调/// </summary>public Action OnBegin;/// <summary>/// 请求完成后的回调/// </summary>private readonly Action<Response> OnComplete;private readonly Dictionary<string, string> Headers;private readonly Dictionary<string, List<string>> Query;public Request(Action<Response> onComplete, int timeout = 10){OnComplete = onComplete;Timeout = timeout;Headers = new Dictionary<string, string>();Query = new Dictionary<string, List<string>>();}public Request(Action<Response> onComplete, string bodyData, int timeout = 10) : this(onComplete, timeout){BodyData = bodyData;}public Request Reset(){IsDone = false;return this;}internal void Invoke(bool succeed, long statusCode, byte[] data, string error){IsDone = true;OnComplete?.Invoke(new Response(succeed, statusCode, data, error));}public Request AddQuery(string key, string value){if (Query.ContainsKey(key) == false){Query[key] = new List<string>();}Query[key].Add(value);return this;}public bool RemoveQuery(string key){return Query.Remove(key);}public Request SetRequestHeader(string key, string value){Headers[key] = value;return this;}public Dictionary<string, string> GetHeaders(){return new Dictionary<string, string>(Headers);}public string GetQueryString(){StringBuilder sb = new StringBuilder();foreach (var kv in Query){if (sb.Length > 0 && kv.Value.Count > 0) sb.Append('&');// 将每个键值对转换为字符串并连接起来var values = string.Join('&', kv.Value.Select(value => $"{kv.Key}={value}"));sb.Append(values);}return sb.ToString();}/// <summary>/// 设置超时时间/// </summary>/// <param name="timeout"></param>/// <returns></returns>public Request SetTimeout(int timeout){Timeout = timeout;return this;}/// <summary>/// 设置重试参数/// </summary>/// <param name="retryCount">重试次数</param>/// <param name="sec">重试间隔(秒)</param>/// <returns></returns>public Request SetRetryOption(ushort retryCount, float retryInterval){RetryCount = retryCount;RetryInterval = retryInterval;return this;}/// <summary>/// 设置Body内容/// </summary>/// <param name="bodyData"></param>/// <returns></returns>public Request SetBodyData(string bodyData){BodyData = bodyData;return this;}/// <summary>/// 设置Body内容,并指定内容类型/// </summary>/// <param name="bodyData"></param>/// <param name="contentType">如:application/json</param>/// <returns></returns>public Request SetBodyData(string bodyData, string contentType){BodyData = bodyData;ContentType = contentType;return this;}/// <summary>/// 设置内容类型/// </summary>/// <param name="contentType">如:application/json</param>/// <returns></returns>public Request SetContentType(string contentType){ContentType = contentType;return this;}}
}
Response.cs
using System.Text;namespace MYTOOL.RestClient
{public class Response{public bool Succeed { get; }public long StatusCode { get; }public byte[] Data { get; }public string Error { get; }public bool HasError => string.IsNullOrEmpty(Error) == false;public Response(bool succeed, long statusCode, byte[] data, string error){Succeed = succeed;StatusCode = statusCode;Data = data;Error = error;}public string GetResponseData(Encoding encoding = null){if (Data == null) return "";encoding ??= Encoding.UTF8;return encoding.GetString(Data);}}
}
使用例子
using MYTOOL.RestClient;
using UnityEngine;public class NewBehaviourScript : MonoBehaviour
{private RestWebClient client;private void Awake(){//初始化client = new RestWebClient(this);}private void Start(){//设置请求完成后回调 与 超时时间Request req = new Request(OnGetBaidu, 30);//设置重试次数 与 重试间隔req.SetRetryOption(3, 0.2f);client.Get("https://www.baidu.com/", req);}void OnGetBaidu(Response resp){if (resp.Succeed){if (resp.StatusCode == 200 || resp.StatusCode == 204){Debug.Log($"请求成功,{resp.GetResponseData()}");}}else{Debug.Log($"请求失败,{resp.Error}");}}
}

相关文章:
Unity UnityWebRequest封装类
简化api调用流程,非常奈斯。 RestWebClient.cs using System; using System.Collections; using UnityEngine; using UnityEngine.Networking;namespace MYTOOL.RestClient {/// <summary>/// UnityWebRequest封装类/// </summary>public class RestW…...
JVM内存划分
Java虚拟机(JVM)的内存划分是指JVM在运行时所使用的内存区域的组织和管理方式。JVM内存主要分为以下几个区域: 堆区(Heap): 用途:用于存储所有对象实例和数组,是JVM中最大的一块内存…...
c++ 全排列
在C中,全排列(permutation)可以使用递归算法或标准库函数来实现。以下是使用递归和STL库std::next_permutation来生成一个集合的全排列的两种方法。 方法一:递归算法 递归方法通过交换元素来生成所有可能的排列组合。 #include…...
未授权访问漏洞系列详解⑤!
Kubernetes Api Server未授权访问漏洞 Kubernetes 的服务在正常启动后会开启两个端口:Localhost Port(默认8080)Secure Port(默认6443)。这两个端口都是提供 Api Server 服务的,一个可以直接通过Web 访问,另一个可以通过 kubectl 客户端进行调用。如果运…...
【CONDA】库冲突解决办法
如今,使用PYTHON作为开发语言时,或多或少都会使用到conda。安装Annaconda时一般都会选择在启动终端时进入conda的base环境。该操作,实际上是在~/.bashrc中添加如下脚本: # >>> conda initialize >>> # !! Cont…...
【网络世界】数据链路层
目录 🌈前言🌈 📁 初识数据链路层 📂 概念 📂 协议格式 📁 MAC地址 📂 概念 📂 与IP地址的区别 📁 MTU 📂 对IP协议的影响 📂 对UDP协议的影响…...
AllReduce通信库;Reduce+LayerNorm+Broadcast 算子;LayerNorm(层归一化)和Broadcast(广播)操作;
目录 AllReduce通信库 一、定义与作用 二、常见AllReduce通信库 三、AllReduce通信算法 四、总结 Reduce+LayerNorm+Broadcast 算子 1. Reduce 算子 2. LayerNorm 算子 3. Broadcast 算子 组合作用 LayerNorm(层归一化)和Broadcast(广播)操作 提出的创新方案解析 优点与潜在…...
2024.8.5 作业
使用有名管道实现,一个进程用于给另一个进程发消息,另一个进程收到消息后,展示到终端上,并且将消息保存到文件上一份 代码: /*******************************************/ 文件名:create.c /********…...
MySQL数据库——数据库的基本操作
目录 三、数据库的基本操作 1.数据库中库的操作 ①创建数据库 ②字符集和校验规则 ③操纵数据库 ④备份与恢复 2.数据库中表的操作 ①创建表 ②查看表 1> 查看表位于的数据库 2>查看所有表 3>查看表中的数据 4>查看创建表的时候的详细信息 ③修改表 …...
SQL数据库语句练习
1、mysql常用的数据类型是_整数(int)__、_小数(decimal)__、_字符串(varchar)__、_日期时间(datetime)___。 2、mysql的约束有__主键(primary key)_、_非空&…...
【Python】常用的pdf提取库介绍对比
提取PDF内容的Python库有多种选择,每个库都有其独特的优缺点。以下是一些常用的库以及它们的优缺点和示例代码: pdfplumberPyMuPDF (fitz)PyPDF2PDFMinerCamelot 1. pdfplumber 优点: 易于使用,提供简单直观的API。能提取文本…...
sbatch提交并行作业 运行python程序 指定输入参数从1到100
#!/bin/bash #SBATCH --job-namemy_python_job #SBATCH --outputmy_python_job_%j.out #SBATCH --errormy_python_job_%j.err #SBATCH --ntasks100# 载入所需模块 # module load python/3.8.5# 执行Python脚本并传递任务ID作为参数 for i in {1..100}; dosrun python my_script…...
OD C卷 - 中庸行者
中庸行者 (200) 给一个m*n的整数矩阵作为地图,矩阵数值为地形的高度,选择图中任意一点作为起点,向左右上下四个方向移动: 只能上坡、下坡,不能走相同高度的点;不允许连续上坡 或者连…...
最新CSS3横向菜单的实现
横向菜单 原始代码: <nav class"list1"><ul><li><a href"#">Shirts</a></li><li><a href"#">Pants</a></li><li><a href"#">Dresses</a>…...
(2024,LlamaGen,Llama,自回归下一token预测,模型扩展)自回归模型优于扩散:Llama 用于可扩展图像生成
Autoregressive Model Beats Diffusion: Llama for Scalable Image Generation 目录 0. 摘要 1. 引言 2. 自回归模型在图像生成中的应用 2.1 概述 2.2 图像 tokenizer 2.3 自回归模型生成图像 2.4 规模扩展 2.5 服务 3. 实验 5. 结论 0. 摘要 我们介绍 LlamaGen&…...
重新安装操作系统的软件都有哪些?
重新安装操作系统关键步骤 重新安装操作系统通常涉及到几个关键步骤:创建可启动媒体、备份现有数据、安装操作系统、以及系统初始化和配置。以下是一些常用工具和软件,它们可以帮助你完成这些步骤: 创建可启动媒体 Rufus:用于W…...
深圳水务展|2025深圳国际水务科技博览会
2025深圳国际水务科技博览会 展会主题: 新质生产力赋能水务产业高质量发展 展会时间:2025年7月24-26日 展会地点:深圳会展中心(福田) 主办单位: 广东省水利学会 深圳市水务学会 协办单位: 中国水利…...
OpenAI not returning a result?
题意:OpenAI 没有返回结果吗? 问题背景: Im trying to use the OpenAI beta but I cant seem to get a result. Im accessing the API via an NPM package (openai-api - npm). I have that setup and working but when I make a request th…...
[Windows]_[初级]_[GetVersionEx获取系统版本错误的原因]
场景 开发WTL/ATL/Win32程序时, 有时候需要获取系统版本号,以便判断用户在使用软件时的系统。在某一天突然发现获取的系统版本号是错的, 一直是版本号6.2.x,什么情况? 说明 如果软件没有针对Win8.1或Win10以上的系统做兼容处理,返回的是Wi…...
2024,Java开发在中国市场还有发展前景吗?
随着2024年的到来,Java作为一种经典而强大的编程语言,依然在中国的软件开发市场中扮演着重要角色。然而,许多人对Java的未来发展前景持有不同的看法。让我们来探讨一下当前情况和未来的走向。 Java程序员真的过剩了吗? 2023年, 各…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
