using Godot; using System; using System.Threading; using BITKit.Packages.Core.LazyLoad; using HttpClient = System.Net.Http.HttpClient; namespace BITKit; public partial class HttpGet : Node,IActivable { /// /// 访问的Url /// [Export] private string url; /// /// 是否启用 /// [Export] public bool Enabled { get; set; } = true; [Signal] public delegate void OnGetEventHandler(string httpContext); [Signal] public delegate void OnExceptionEventHandler(string exception); /// /// 请求数据的间隔 /// private readonly IntervalTimer _intervalTimer = new(1); /// /// http客户端 /// private readonly HttpClient httpClient=new(); /// /// 取消令牌,用于取消Http Get /// private CancellationToken _cancellationToken; private bool allowNextRequest = true; public override void _Ready() { _cancellationToken = new CancellationToken(); } /// /// 物理帧用于控制并发和间隔的同时请求数据 /// /// public override void _PhysicsProcess(double delta) { if (Enabled is false) return; //等待依赖加载 //请求间隔控制+请求并发控制 if (_intervalTimer.Allow is false) return; //如果url为空 if (string.IsNullOrEmpty(url)) return; //发送请求 if (allowNextRequest) Request(); } private async void Request() { allowNextRequest = false; //获取json try { var json = await httpClient.GetStringAsync(url, _cancellationToken); //取消执行,如果已取消令牌 _cancellationToken.ThrowIfCancellationRequested(); //调用回调 EmitSignal(nameof(OnGet), json); } catch (InvalidOperationException) { BIT4Log.Warning(url); } catch (OperationCanceledException) { } catch (Exception e) { EmitSignal(nameof(OnException), e.Message); } allowNextRequest = true; } public void SetActive(bool active) => Enabled=active; }