小鱼塘--自说自话的地方

  • 小玩意
  • 小想法
记录自己技术和想法地方
  1. 首页
  2. c#
  3. 正文

TouchSocket Http client使用例子

16 5 月, 2023 2049点热度 0人点赞 0条评论
内容目录

背景

因为c# httpclient会出现无法访问网络情况,当IE无法访问网络情况,这个因为由于windows 底层实现导致的,只能修复IE才能上网,但这这样子用户体验不好,那么我就找c# 完全自己实现httpclient,找了好多发现都是底层依赖httpwebrequest,这个还是依赖IE,最后找到这个touchsocket这个网络库,然后我用它的官方例子却跑一些http请求会失败,我自己抓包分析才发现它写的例子是错误,http host不能那么设置,因为HTTP server会识别,但它带有端口可能就出现错误。

例子

namespace ConsoleApp1
{
    class Program
    {

        static public async Task<HttpResponse> HTTPGet(string raw_url)
        {
            HttpResponse respose = null;
            await Task.Run(() =>
            {
                Uri url = new Uri(raw_url);
                int index = url.AbsoluteUri.LastIndexOf(url.AbsolutePath);

                string new_ip_host = url.AbsoluteUri.Substring(0, index);
                string user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42";
                TouchSocket.Http.HttpClient client = new TouchSocket.Http.HttpClient();
                client.Setup(new TouchSocketConfig()
                    .SetRemoteIPHost(new IPHost(new_ip_host)))
                    .Connect();//先做连接

                HttpRequest request = new HttpRequest();
                request
                    .InitHeaders()
                    .SetHeader(HttpHeaders.UserAgent, user_agent)
                    .SetHost(url.Host)
                    .SetUrl(url.AbsolutePath)
                    .AsGet();

                try
                {
                    //必须这么写,如用SetHeader会增加一个close,既包含keep-alive又close了,这样子逻辑有点混乱
                    request.Headers["connection"] = "close"; //因为目前这个写法无法复用keep-alive,那么直接用close就可以了
                    respose = client.Request(request, timeout: 1000 * 10);    //这个等待结果完成
                }
                catch (Exception)
                {

                }

            });

            return respose;
        }

        public static async Task<HttpResponse> HTTPostJSON(string raw_url, string json_text)
        {

            HttpResponse respose = null;
            await Task.Run(() =>
            {
                Uri url = new Uri(raw_url);
                string new_ip_host = url.AbsoluteUri.Replace(url.AbsolutePath, "");
                string user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42";
                TouchSocket.Http.HttpClient client = new TouchSocket.Http.HttpClient();
                client.Setup(new TouchSocketConfig()
                    .SetRemoteIPHost(new IPHost(new_ip_host)))
                    .Connect();//先做连接

                HttpRequest request = new HttpRequest();
                request
                    .InitHeaders()
                    .SetHeader(HttpHeaders.Connection, "Close")      //因为目前这个写法无法复用keep-alive,那么直接用close就可以了
                    .SetHeader(HttpHeaders.ContentType, "application/json")
                    .SetHeader(HttpHeaders.UserAgent, user_agent)
                    .SetHost(url.Host)
                    .SetUrl(url.AbsolutePath)
                    .AsPost();

                try
                {
                    //必须这么写,如用SetHeader会增加一个close,既包含keep-alive又close了,这样子逻辑有点混乱
                    request.Headers["connection"] = "close"; //因为目前这个写法无法复用keep-alive,那么直接用close就可以了
                    //设置body的内容
                    request.SetContent(json_text);
                    respose = client.Request(request, timeout: 1000 * 10);    //这个等待结果完成
                }
                catch (Exception)
                {

                }

            });

            return respose;
        }

        static async void TestPost()
        {
            Dictionary<string, object> object_dic = new Dictionary<string, object>();
            object_dic["id"] = 1;
            object_dic["msg"] = "hello world";
            var str = JsonFastConverter.JsonTo(object_dic);
            var r = await HTTPostJSON("http://wwww.baidu.com/you", str);//这里构建一个没有用,只是为了抓包用HTTP的包,看格式是否正确
            Console.WriteLine(r.GetBody());
        }

        static async void TestGet()
        {
            var r = await HTTPGet("http://u.tools/docs/guide/about-uTools.html#utools-%E6%98%AF%E4%BB%80%E4%B9%88");
            if(r != null)
            {
                Console.WriteLine(r.GetBody());
            }
        }
        static void Main(string[] args)
        {
            TestGet();
            Console.ReadLine();
        }
    }
}

总结

我只是做了简单封装,用url来解析域名,方便使用,同时我没用keep-alive 因为这种写法没复用连接,那么消耗几分钟断开连接也没必要,我猜测微软的httpclient有复用,因为官方都推荐用单例。官方例子一定要设置证书,目前最新代码是不用设置,默认检测https就会设置证书。

这个网络库代码看了一下有点像java风格,各种接口抽象,各种封装,代码阅读不是那么直观,我现在反而不喜欢过多封装,不过这是每个人风格。

标签: c# http client socket
最后更新:17 5 月, 2023

小鱼儿

爱研究技术,爱玩LOL

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2022 小鱼塘. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

湘ICP备18005349号