.NetCore Flurl.Http 集成 Microsoft.Extensions.ServiceDiscovery

        .Net8.0及以上版本,微软官方提供了服务发现Nuget包Microsoft.Extensions.ServiceDiscovery,能够对 HttpClient 请求服务进行服务发现和解析,对于轻量级Flurl.Http 来说,也可以进行集成,主要思路是通过HttpClientFactory 构建HttpClient 实例,调用new FlurlClient(httpClientFactory.CreateClient()) 实现,以下具体介绍集成过程同时与常规的 HttpClient 写法做一个比较。

服务发现
引入依赖包

        Microsoft.Extensions.ServiceDiscovery 当前对应版本为9.0.0。可以通过Nuget 管理器引入到项目中。

dotnet add package Microsoft.Extensions.ServiceDiscovery

基础配置服务

主类中主体结构如下:
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // 注册服务
            IServiceCollection services = builder.Services;

            // 添加服务发现
            services.AddServiceDiscovery();

            // 设置httpclient构建添加服务发现
            services.ConfigureHttpClientDefaults(static http =>
            {
                // Turn on service discovery by default
                http.AddServiceDiscovery();
            });

            // 注册请求服务
            services.AddSingleton<MapClientService>();

            var app = builder.Build();

            app.MapControllers();

            app.Run();
        }
    
其中,AddServiceDiscovery() 注册服务发现。

builder.Services.AddServiceDiscovery();

MapClientService 实际请求处理类。

// 注册请求服务
services.AddSingleton<MapClientService>();
ConfigureHttpClientDefaults(static http =>{})添加全局HttpClient 实例应用服务发现。

// 设置httpclient构建添加服务发现
services.ConfigureHttpClientDefaults(static http =>
{
    // Turn on service discovery by default
    http.AddServiceDiscovery();
});

添加服务发现配置appsettings.json 根层级。

{
    "Services": {
        "mapservice": { // 服务名称
          "http": [ // http请求
            "192.168.31.116:6003" // 服务实际服务地址和端口
          ]
    }
  }
}

请求实现类
普通工厂创建实例

private readonly MapOptions _options;
private readonly IDistributedCache _cache;
private readonly IHttpClientFactory _httpClientFactory;
public MapClientService(IOptions<MapOptions> map,IDistributedCache cache,IHttpClientFactory httpClientFactory)
{
    _options = map?.Value;
    _cache = cache;
    _httpClientFactory = httpClientFactory;
}
// 请求服务地址(期望通过服务发现进行解析)
private const string _url = "http://mapservice";
public const string token = "/api/identity/token";
public async Task<string> Token()
{
    string key =  _cache.GetString(token);
    if (key == null) {
        var data = new
        {
            grantType = "password",
            account = _options.Uname,
            password = _options.Pwd
        };
        // 构建请求--------------------------------------------------
        HttpClient httpClient = _httpClientFactory.CreateClient();
        httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
        HttpRequestMessage httpRequest = new HttpRequestMessage();
        httpRequest.Method = HttpMethod.Post;
        httpRequest.RequestUri = new Uri($"{_url}{updateMapState}");
        httpRequest.Content = new StringContent(JsonSerializer.Serialize(data));
        httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest);
        var msg = await httpResponse.Content.ReadAsStringAsync();
        AjaxResult<TokenResult> result = JsonSerializer.Deserialize<AjaxResult<TokenResult>>(msg);
        if (result.Type == 200)
        {
            key = result.Data.AccessToken;
            _cache.SetString(token, key,new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300)});
        }
    }
    return key;
}

运行输入日志如下:

info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
      Start processing HTTP request POST http://mapservice/api/urlmap/updateurlmapstate
info: System.Net.Http.HttpClient.Default.ClientHandler[100]
      Sending HTTP request POST http://192.168.31.116:6003/api/urlmap/updateurlmapstate

使用Flurl.Http请求

        直接使用Flurl.Http 对之前的HttpClientFactory 进行改造。

using Flurl.Http;

private readonly MapOptions _options;
private readonly IDistributedCache _cache;
private readonly IFlurlClient _flurlClient;
public MapClientService(IOptions<MapOptions> map,IDistributedCache cache)
{
    _options = map?.Value;
    _cache = cache;
}
// 请求服务地址(期望通过服务发现进行解析)
private const string _url = "http://mapservice";
public const string token = "/api/identity/token";
public async Task<string> Token()
{
    string key =  _cache.GetString(token);
    if (key == null) {
        var data = new
        {
            grantType = "password",
            account = _options.Uname,
            password = _options.Pwd
        };
        // 构建请求--------------------------------------------------
        var result = await $"{_url}{token}".PostJsonAsync(data).ReceiveJson<AjaxResult<TokenResult>>();
        
        if (result.Type == 200)
        {
            key = result.Data.AccessToken;
            _cache.SetString(token, key,new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300)});
        }
    }
    return key;
}

通过FlurlClient并支持服务发现

private readonly MapOptions _options;
private readonly IDistributedCache _cache;
private readonly IFlurlClient _flurlClient;
public MapClientService(IOptions<MapOptions> map,IDistributedCache cache,IHttpClientFactory httpClientFactory)
{
    _options = map?.Value;
    _cache = cache;
    _flurlClient = new FlurlClient(httpClientFactory.CreateClient());
}
// 请求服务地址(期望通过服务发现进行解析)
private const string _url = "http://mapservice";
public const string token = "/api/identity/token";
public async Task<string> Token()
{
    string key =  _cache.GetString(token);
    if (key == null) {
        var data = new
        {
            grantType = "password",
            account = _options.Uname,
            password = _options.Pwd
        };
        // 构建请求--------------------------------------------------
        var result = await _flurlClient.Request($"{_url}{token}").PostJsonAsync(data).ReceiveJson<AjaxResult<TokenResult>>();

        if (result.Type == 200)
        {
            key = result.Data.AccessToken;
            _cache.SetString(token, key,new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300)});
        }
    }
    return key;
}

运行项目,程序输入如下,与HttpClientFactory 构建实例发起请求输出一致。

info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
      Start processing HTTP request POST http://mapservice/api/identity/token2
info: System.Net.Http.HttpClient.Default.ClientHandler[100]
      Sending HTTP request POST http://192.168.31.116:6003/api/identity/token2

        可以发现,对应请求日志输出,两者并无差异,也能够成功解析,表示通过IHttpClientFactory 构建实例能够与Flurl.Http 中进行集成。既简化了简单的接口请求,又能够使用HttpClient 官方提供的一些扩展功能。

参考文章:Flurl.Http集成Microsoft.Extensions.ServiceDiscovery - 关关长语 - 博客园 

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值