我有一个API中间层,它捕获请求,生成一个令牌,然后将该请求传递到预期的API端点。一次只能创建一个令牌,因此每个请求都需要检查是否存在有效的令牌并使用它,或者创建一个新的令牌。如果中间层API同时收到多个请求,它仍然应该只创建一个令牌。
为此,我使用了SemaphoreSlim:
接收请求以检查某个东西的当前版本的控制器:
[ApiController]
[Route("[controller]")]
[AuthorizationKey]
public class Controller : ControllerBase
{
private readonly ILogger<Controller> Logger;
private readonly Services Services;
public Controller(ILogger<Controller> logger, Services services)
{
Logger = logger;
Services = services;
}
[HttpGet]
[Route("version")]
[ResponseCache(NoStore = true, Duration = 0, Location = ResponseCacheLocation.None)]
public async Task<ActionResult> Version()
{
try
{
var result = await Services.GetVersionAsync();
var response = result.Content.ReadAsStringAsync();
if (result.StatusCode == HttpStatusCode.OK)
{
return Ok(response.Result);
}
else if (result.StatusCode == HttpStatusCode.Unauthorized)
{
return StatusCode(401, response.Result);
}
else
{
return StatusCode(500, response.Result);
}
}
catch (Exception ex)
{
return StatusCode(500);
}
}
}
下面是我服务的类:
public class Services
{
private readonly ILogger<Services> Logger;
private readonly IConfiguration Configuration;
private readonly IHttpClientFactory HttpClientFactory;
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
public Services(ILogger<Services> logger, IConfiguration configuration, IHttpClientFactory httpClientFactory)
{
Logger = logger;
Configuration = configuration;
HttpClientFactory = httpClientFactory;
}
public async Task<HttpResponseMessage> GetVersionAsync()
{
var httpClient = await CreateHttpClient();
var response = await httpClient.GetAsync(Configuration["VERSION_ENDPOINT"]);
return response;
}
#region Helpers
private async Task<HttpClient> CreateHttpClient()
{
var token = await GetAccessTokenAsync();
var httpClient = HttpClientFactory.CreateClient();
httpClient.BaseAddress = new Uri(Configuration["API_URI"]);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return httpClient;
}
private async Task<string> GetAccessTokenAsync()
{
await _semaphore.WaitAsync();
try
{
//Checks for a token in a table and returns it if it is valid, or gets a new one if one does not exist
/if no token, then it calls RequestAccessTokenAsync()
}
finally
{
_semaphore.Release();
}
}
private async Task<TokenResponse> RequestAccessTokenAsync()
{
//Gets a new token from a service
}
#endregion
}
如果我同时提交多个请求,它会创建多个令牌。我提交的请求数量并不总是1比1。例如,我提交了2个请求,它创建了2个令牌,3个请求,它创建了2个令牌,现在我只提交了10个请求,它创建了7个令牌,但无论哪种方式,我都只希望一次创建1个有效令牌。
1条答案
按热度按时间jyztefdp1#
将以下代码切换到静态解决了这个问题。再次感谢用户“已删除”的帮助。