using Consul; using Furion; using Furion.FriendlyException; using Furion.HttpRemote; using Microsoft.Extensions.Caching.Distributed; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { public class ResourceHttpUtils { private readonly IDistributedCache distributedCache; private readonly IHttpRemoteService httpRemoteService; private readonly IConsulClient consulClient; public ResourceHttpUtils( IDistributedCache distributedCache, IHttpRemoteService httpRemoteService, IConsulClient consulClient) { this.distributedCache = distributedCache; this.httpRemoteService = httpRemoteService; this.consulClient = consulClient; } /// /// 发送HTTP请求 /// /// /// /// /// /// public async Task SendHttpAsync( TRequest request, IResourceHttpProvider provider = null) where TRequest : class, new() { var requestTypeFullName = typeof(TRequest).FullName; var jsonResourceModels = await distributedCache.GetStringAsync($"ResourceModel|{requestTypeFullName}"); var resource = jsonResourceModels.JsonTo(); var domain = await GetHealthyServiceDomain(resource); var builder = HttpRequestBuilder.Create(resource.GetHttpMethod(), $"{domain}{resource.Route}"); if (resource.Method == EnumResourceMethod.Get) builder = builder.WithQueryParameters(request); else builder = builder.SetJsonContent(request); provider = provider ?? new DefaultResourceHttpProvider(); builder = provider.AddAuthentication(builder); var response = await provider.SendAsAsync(httpRemoteService, builder); return response; } /// /// 获取健康服务域名 /// /// /// public async Task GetHealthyServiceDomain(ResourceModel resource) { var queryResult = await consulClient.Health.Service(resource.ServiceName, null, true); if (queryResult.StatusCode != System.Net.HttpStatusCode.OK) throw Oops.Oh(EnumErrorCodeType.s404, $"微服务{resource.Service}"); var domains = queryResult.Response .Select(s => $"http://{s.Service.Address}:{s.Service.Port}") .ToList(); if (domains.IsNull()) throw Oops.Oh(EnumErrorCodeType.s404, $"微服务{resource.Service}"); // 轮询选择实例 int randomIndex = new Random().Next(domains.Count); return domains[randomIndex]; } } }