Net.Like.Xue.Tokyo/Assets/BITKit/Unity/Scripts/Http/HttpService.cs

156 lines
3.6 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
using Debug = UnityEngine.Debug;
using Timer = System.Timers.Timer;
namespace BITKit.Http
{
public class HttpService : MonoBehaviour
{
[Header(Constant.Header.Settings)]
[SerializeReference,SubclassSelector] private IReference url;
[SerializeField] private double interval;
[SerializeField] private CollisionDetectionMode detectionMode;
[Header(Constant.Header.Output)]
[SerializeField] private UnityEvent<string> output;
[SerializeField] private UnityEvent<string> onException;
[SerializeField] private UnityEvent<int> onCalculateLength;
[Header(Constant.Header.Optional)]
[SerializeField] private Optional<string> overrideResponse;
[Header(Constant.Header.Debug)]
[SerializeField, ReadOnly] private double time;
[SerializeField, ReadOnly] private bool isConnected;
private readonly Timer timer = new()
{
AutoReset = true
};
private readonly HttpClient _httpClient = new();
private bool _enabled;
private void OnEnable()
{
_enabled = true;
}
private void OnDisable()
{
_enabled = false;
}
private void Start()
{
timer.Interval = interval*1000;
timer.Elapsed += (x, y) => OnUpdate();
timer.AutoReset = detectionMode switch
{
CollisionDetectionMode.ContinuousDynamic => true,
CollisionDetectionMode.ContinuousSpeculative => true,
CollisionDetectionMode.Continuous => true,
CollisionDetectionMode.Discrete => false,
_ => throw new ArgumentOutOfRangeException()
};
timer.Start();
destroyCancellationToken.ThrowIfCancellationRequested();
}
private void OnDestroy()
{
timer.Stop();
timer.Dispose();
}
private async void OnUpdate()
{
try
{
if (_enabled)
{
if (overrideResponse.Allow)
{
await UniTask.SwitchToMainThread();
try
{
output.Invoke(overrideResponse.Value);
}
catch (Exception e)
{
Debug.LogException(e);
}
isConnected = true;
}
else
{
Stopwatch stopwatch = new();
stopwatch.Start();
//var result = await _httpClient.GetStringAsync(url.Value);
var response = await _httpClient.GetAsync(url.Value,destroyCancellationToken);
if (destroyCancellationToken.IsCancellationRequested) return;
var result =await response.Content.ReadAsStringAsync();
if (destroyCancellationToken.IsCancellationRequested) return;
stopwatch.Stop();
time =System.TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds;
await UniTask.SwitchToMainThread();
if (destroyCancellationToken.IsCancellationRequested) return;
try
{
var length = int.Parse(response.Content.Headers.First(h => h.Key.Equals("Content-Length")).Value.First());
onCalculateLength.Invoke(length);
}
catch (InvalidOperationException)
{
}
if (response.StatusCode is not System.Net.HttpStatusCode.OK)
{
onException.Invoke(result);
}
else
{
try
{
output.Invoke(result);
}
catch (Exception e)
{
Debug.LogException(e);
}
}
isConnected = true;
}
}
}
catch(OperationCanceledException){}
catch (Exception e)
{
BIT4Log.LogException(e);
isConnected = false;
}
if (timer.AutoReset == false)
{
if(destroyCancellationToken.IsCancellationRequested)return;
timer.Start();
}
}
}
}