首页 > 其他分享 >Flurl.Http集成Microsoft.Extensions.ServiceDiscovery

Flurl.Http集成Microsoft.Extensions.ServiceDiscovery

时间:2024-12-30 22:52:27浏览次数:1  
标签:Http cache http token Extensions key new Flurl options

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

服务发现

引入依赖包

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

dotnet nuget add pack 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 官方提供的一些扩展功能。

标签:Http,cache,http,token,Extensions,key,new,Flurl,options
From: https://www.cnblogs.com/guanguanchangyu/p/18642642

相关文章

  • 【JavaSE】【网络协议】HTTP 请求和响应
    一、HTTP请求1.1请求格式请求格式:首行+请求头(header)+空行+正文(body)1.2首行组成首行组成:请求方法+URL+版本号。使用“空格”将他们分隔开。1.2.1请求方法方法说明支持的HTTP版本GET获取资源1.01.1POST传输实体主体1.01.1PUT传输文件1.01.1DELETE删除文件1.01.......
  • 搬运优秀随笔:https://www.cnblogs.com/gaoshidong
    一、第一章:初识Java与面向对象程序设计Java简介:Java是一种面向对象的程序设计语言,具有跨平台、安全性高、可移植性强等特点。面向对象程序设计概述:面向对象是一种程序设计思想,将现实世界的事物抽象为对象,通过对象之间的交互来完成程序的功能。Java开发环境搭建:介绍了Java......
  • 使用 httputils + sbe (Simple Binary Encoding) 实现金融级 java rpc
    1、认识SimpleBinaryEncoding(sbe)高性能Java库Agrona的主要目标是减少性能瓶颈,通过提供线程安全的直接和原子缓冲区、无装箱操作的原始类型列表、开散列映射和集合以及锁-free队列等,为开发者在处理并发和低延迟场景时提供强大工具。SimpleBinaryEncoding(sbe)是Agr......
  • 异步爬虫之aiohttp的使用
    在上一篇博客我们介绍了异步爬虫的基本原理和asyncio的基本用法,并且在最后简单提及了使用aiohttp实现网页爬取的过程。本篇博客我们介绍一下aiohttp的常见用法。基本介绍前面介绍的asyncio模块,其内部实现了对TCP、UDP、SSL协议的异步操作,但是对于HTTP请求来说,就......
  • 使用Windows和FFmpeg 将https://xxx.com/xx.m3u8 推流到B站
    要将一个.m3u8流推送到B站(哔哩哔哩直播平台),你可以使用FFmpeg工具。下面是一个大致的步骤:前提条件你已经拥有B站的直播推流地址。已经安装并配置了FFmpeg。将FFmpeg添加到Windows环境变量打开系统环境变量设置:方法1:右键点击“此电脑”或“计算机”,选择“属......
  • 【PHP应用】使用http通道连接数据库
    #Navicat#PHP#MySQL办公网和内网的网络并不是完全互通的,內网只支持特定端口范围供办公网访问,因此如果数据库的端口不在这个端口范围内,那么就无法在mac上使用mysql客户端连接内网的数据库。在开发过程中,有很多要连接的数据库,有的端口在特定端口范围,有的不在,平常都是在开发机上......
  • linux网络 | 深度学习http的相关概念
        前言:本节内容讲述http。本节主要讲述http的一些相关概念,见一见的http的样子。在文章中,博主将先会重新回忆一下OSI的七层模型。然后讲两个前置知识。最后就是带着友友见一见http的格式。做完这些,本节内容就算是圆满结束。而后面的章节还会带着友友们模拟ht......
  • http2和http3
    HTTP/2和HTTP/3是HTTP协议的升级版本,主要为了解决HTTP/1.x协议的性能瓶颈和安全性问题。以下是它们的主要目标和解决的问题:HTTP/2的主要目标和解决的问题1.性能优化多路复用(Multiplexing):HTTP/1.x中,每个请求需要单独建立一个TCP连接,或者使用持久连接(Keep-Alive)......
  • 云计算学习架构篇之HTTP协议、Nginx常用模块与Nginx服务实战
    一.HTTP协议讲解1.1rsync服务重构```bash部署服务端:1.安装服务[root@backup~]#yum-yinstallrsync2.配置服务[root@backup~]#vim/etc/rsyncd.confuid=rsyncgid=rsyncport=873fakesuper=yesusechroot=nomaxconnections=200timeout=600......
  • 如何开启强制HTTPS跳转并确保兼容HTTP访问?
    您好,为了确保您的网站能够强制跳转到HTTPS协议并兼容HTTP访问,您可以按照以下步骤进行设置:理解强制HTTPS跳转的作用:强制HTTPS跳转意味着所有通过HTTP协议访问的请求都会自动重定向到HTTPS协议。这样可以提高网站的安全性和用户体验。同时,确保HTTP和HTTPS之间的兼容性非常重要,......