using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net.Http.Json;
using System.Net;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
using System.Security.Authentication.ExtendedProtection;
using Newtonsoft.Json.Linq;
using System.Text.Json.Serialization.Metadata;

namespace HttpClientStudy.UnitTest.HttpClients
{
    /// <summary>
    /// HttpClient 常见问题测试
    /// </summary>
    public class HttpClientQuestTest
    {
        private readonly ITestOutputHelper _logger;

        public HttpClientQuestTest(ITestOutputHelper outputHelper)
        {
            _logger = outputHelper;
        }

        /// <summary>
        /// 多HttpClient实例问题
        /// 1、HttpClient虽然继承了 IDisposable 接口,但它是可以被共享的,且线程安全。Using使用并不能立即释放
        /// 2、网络特性:虽然HttpClient客户端断开,但Web服务并不知道,连接依然存在,状态为 “ TIME_WAIT”(继续等待看是否还有延迟的包会传输过来。)
        ///    Windows默认为 240s
        /// 引发常见问题:
        /// 1、HttpClient 多实例并存,有很大资源消耗;
        /// 2、在高并发的情况下,连接来不及释放, socket 被耗尽: 程序异常
        /// 3、连带着会出现“各种套接字问题” 
        /// 
        /// 查看问题:
        /// 程序并发或多次请求后,通过 netstate 查看下 TCP 连接情况:有很多 TIME_WAIT 状态连接;很可能程序异常;
        /// 
        /// 解决:
        /// 1、复用HttpClient
        /// 2、HttpClientFactory
        /// 3、解决DNS问题可以给HttpClient传参:SocketsHttpHandler
        /// </summary>
        /// <returns></returns>
        [Fact]
        public async Task Multi_ClientObject_Test()
        {
            for (int i = 0; i < 100; i++)
            {
                HttpClient httpClient = new HttpClient();

                var responseMessage = await httpClient.GetAsync(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/health");

                responseMessage.EnsureSuccessStatusCode();
            }
        }

        [Fact]
        public async Task Multi_ClientObject2_Test()
        {
            HttpClient httpClient = new HttpClient()
            {
                BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl)
            };
            for (int i = 0; i < 100; i++)
            {
                var responseMessage = await httpClient.GetAsync("/api/health");

                responseMessage.EnsureSuccessStatusCode();
            }
        }
    }
}