using Godot; using System; using System.Threading; using BITKit.Packages.Core.LazyLoad; 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); /// /// 最大并行请求数量 /// private readonly LimitTimes limitConcurrent =new (1); /// /// 请求数据的间隔 /// private readonly IntervalTimer _intervalTimer = new(1); /// /// http客户端 /// private readonly ServiceLoader httpClient=new(); /// /// 取消令牌,用于取消Http Get /// private CancellationToken _cancellationToken; public override void _Ready() { _cancellationToken = new CancellationToken(); } /// /// 物理帧用于控制并发和间隔的同时请求数据 /// /// public override void _PhysicsProcess(double delta) { if(Enabled is false)return; //等待依赖加载 //请求间隔控制+请求并发控制 if (_intervalTimer.Allow is false || httpClient.IsLoaded is false) return; //如果url为空 if (string.IsNullOrEmpty(url)) return; if (!limitConcurrent.AllowOnly) return; //提交并发 limitConcurrent.CanUpdate(); //发送请求 Request(); } private async void Request() { //获取json try { var json = await httpClient.Value.GetStringAsync(url, _cancellationToken); //取消执行,如果已取消令牌 _cancellationToken.ThrowIfCancellationRequested(); //调用回调 EmitSignal(nameof(OnGet), json); } catch (InvalidOperationException) { BIT4Log.Warning(url); //返回并发数量 limitConcurrent.Release(); } catch (OperationCanceledException) { //返回并发数量 limitConcurrent.Release(); } } public void SetActive(bool active) => Enabled=active; }