前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dotnet 6 精细控制 HttpClient 网络请求超时

dotnet 6 精细控制 HttpClient 网络请求超时

作者头像
郑子铭
发布2023-08-30 08:25:20
3170
发布2023-08-30 08:25:20
举报
文章被收录于专栏:DotNet NB && CloudNative

本文告诉大家如何在 dotnet 6 下使用 HttpClient 更加精细的控制网络请求的超时,实现 HttpWebRequest 的 ReadWriteTimeout 功能

在 dotnet 6 下 HttpClient 只是一个包装类,实际的网络请求的核心实现是通过 SocketsHttpHandler 实现的。

在 HttpClient 里,由于 HttpClient 自带的 Timeout 碰触不到底层网络,导致了 Timeout 属性控制范围太广,很多业务上都不合适使用,比如做大文件上传,自然在上传过程中就超时了,如果用户的网络上传速度不快。在 HttpClient 里面,设置 Timeout 表示设置整个网络请求过程的总超时时间。如果只是期望设置连接超时,那自然是做不到的

既然实际的网络是 SocketsHttpHandler 实现的,在 SocketsHttpHandler 可以进行更加精细的控制,例如通过 ConnectTimeout 属性即可用来控制连接的超时时间

代码语言:javascript
复制

        var handler = new SocketsHttpHandler()
        {
            ConnectTimeout = TimeSpan.FromSeconds(10),
        };
        var client = new HttpClient(handler);

这里值得敲黑板的是在 dotnet 6 下,将会大量的复用连接,也就是如果不逗比的情况下,多次对相同的链接请求,在时间距离不远的前提下,是可以复用连接的,不需要做重复的连接。特别是在设置 SocketsHttpHandler 的 EnableMultipleHttp2Connections 为 true 再加上服务器端也支持 Http 2 的多路复用情况下

如果是想和 HttpWebRequest 一样控制 ReadWriteTimeout 的时间,在 dotnet 6 下,可以对请求和响应,也就是发送和接收做分别的超时控制,这就是用到了 dotnet 6 新的 ConnectCallback 属性实现,例子代码如下

代码语言:javascript
复制

        handler.ConnectCallback = async (context, cancellationToken) =>
        {
            var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

            try
            {
                socket.NoDelay = true;

                // 这里可以自己偷偷改掉域名哦,也就是将原本请求的域名修改为一个奇怪的域名。这里偷偷改了,团队的其他伙伴可是很难调试出来的哦
                await socket.ConnectAsync(context.DnsEndPoint, cancellationToken)
                // 配置异步等待后不需要回到原来的线程
                .ConfigureAwait(false);

                // 发送的超时时间,相当于请求的超时
                socket.SendTimeout = (int) TimeSpan.FromSeconds(10).TotalMilliseconds;
                // 接收的超时时间,相当于响应的超时
                socket.ReceiveTimeout = (int) TimeSpan.FromSeconds(5).TotalMilliseconds;
            }
            catch
            {
                socket.Dispose();
                throw;
            }

            // 在 NetworkStream 里,设置 ownsSocket 参数为 true 将会在 NetworkStream 被释放的时候,自动释放 Socket 资源
            return new NetworkStream(socket, ownsSocket: true);
        };

可以看到 HttpClient 的控制是比 HttpWebRequest 更强的,可以分别控制请求和响应的超时

另外,这里的 ConnectCallback 也如上文描述,由于 HttpClient 将会尽可能复用连接,不一定每次请求都会进来,建议不要将配置作为动态配置,想要根据业务动态决定超时时间是不靠谱的行为,这里应该是初始化过程,给定准确的值

回顾一下,控制网络总超时,使用 HttpClient 自带的 Timeout 属性

控制网络的连接超时,使用 SocketsHttpHandler 的 ConnectTimeout 属性

控制网络的请求超时,使用 Socket 的 SendTimeout 属性

控制网络的响应超时,使用 Socket 的 ReceiveTimeout 属性

更多请参阅:

https://blog.lindexi.com/post/dotnet-6-%E4%BD%BF%E7%94%A8-HttpClient-%E7%9A%84%E8%B6%85%E6%97%B6%E6%9C%BA%E5%88%B6.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档