tangyanzhi1111
  • 这几天发现,.Net Core核心中的核心,也就是作为服务器的监听部分,居然用的是Node.Js的LibUv。.Net Core 作为微软最新的一款开源技术栈,其最大的创新就是用KestrelHtppServer构建了自己的专属服务器,取代了传统的IIS作为服务器,也是为了对抗Java Tomcat ,Apache的利器。这款KestrelHtppServer的核心正是 LibUv。

  •  

  • 在.Net Core中,当我们构建如下代码:

  •   public static void Main(string[] args)
            {
                BuildWebHost(args).Run();
            }

            public static IWebHost BuildWebHost(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>()
                    .Build();

    BuildWebHost(args).Run()这个Run是整个程序启动的关键,也是其宿主WebHost启动监听的开始。

  •  

  •  

  • BuildwebHost(args)经过一系列运行,返回WebHost实例,WebHost调用Microsoft.AspNetCore.Hosting类库下面的扩展类WebHostExtensions的方法Run方法。

  • public static void Run(this IWebHost host)
    {
    host.RunAsync().GetAwaiter().GetResult();
    }

  •  


  • Host.RunAsync()调用了Microsoft.AspNetCore.Hosting.Internal下面的StartAsync。StartAsync通过控制反转取得KeStrelHttpServer的实例。 Server = _applicationServices.GetRequiredService<IServer>();然后调用Server.StartAsync.。程序控制来到了KeStrelHtppServer。KeStrelHtppServer里面通过LibUvTransport工厂类LivUvTransportFactory,Create了一个LivUvTransport。同时附带了LibuvFunctions实例,和一个LibUvTransportContext的上下文,以及节点信息EndPoint。然后启动Transport.BindAsync的异步绑定。

  •  

  •  

  • 在TranSport里面会看到我们熟悉的监听类Listener的实例化,绑定,监听。这个过程不是用到.Net 之前提供的监听类TcpListener来监听客户端运行情况,以及返回结果。恰恰相反,它刚好用到的是LivUV。

  • 具体代码以及注解如下:

  •  

  •  

  • listener.ListenSocket = listener.CreateListenSocket();//调用LivUv创建一个服务端Socket
    socket.Init(Thread.Loop, Thread.QueueCloseHandle);//初始化LivUvLoopHandle,和Server Socket
    listener.ListenSocket.Listen(LibuvConstants.ListenBacklog, ConnectionCallback, listener);
    ThrowIfErrored(_uv_listen(handle, backlog, cb));//把服务端Socket传递到LibUv,以便回调函数创建客户端,以及服务端Accept
    客户端。


  • acceptSocket = CreateAcceptSocket();//创建客户端Socket
    socket.Init(Thread.Loop, Thread.QueueCloseHandle);//无论客户端还是服务端LivUv,Init函数的第一个参数都是Tread[0].Loop,
    第二个参数分别为先初始化服务端,后初始化客户端。
    listenSocket.Accept(acceptSocket);//listenSocket服务端,acceptSocket客户端。
    DispatchConnection(acceptSocket);//当监听到有数据进入,DispatchConnection接收当前客户端传递的数据进行处理。
    //DispatchConnection里面有个重要的功能,就是执行.NetCore里面中间件的最里层的匿名Lamada完成NetCore最后的输出。
    Listen里面接受了KeStrelHtppServer传递过来的EndPoint,绑定了端口和IP地址。在利用LibUv核心库,完成了整个过程的绑定与监听,以及客户端传来数据的处理。

  • LivbUV在.Net Core里面实现其实就几个步骤

  •  

  •  

  • 1.利用LibUV库Init了一个UvLoopHandle(Thread.StartAsync)

  • 2.利用LibUV库Init了一个UvAsyncHandle,UvLoopHandle 在前,AsyncHandle在后。(Thread.StartAsync)

  • 3.利用LibUV库创建了一个套接字Socket,实际上是服务端的 Server用来监听客户端。也是Loop在前,这个Socket在后。(CreateSocket方法)

  • 4.绑定了KeStrelHttpServer传递过来的EndPoint,百年规定IP地址和Port以便监听(CreateSocket方法)。

  • 5.开启LibUV 监听,实际上是把第3,4两步创建的Server套接字,传递到回调函数调用回调函数,创建客户端Socket 。

  • 6..创建客户端Socket ,Loop在 ,客户端Socket在后。

  • 7.保持监听状态,ServerSocket.Accpet(ClientSocket)。

  •  

  •  

  • 上面的Init ,Listen,Accept调用NativeMethods方法分别如下:

  • 首先引入非托管类库

  •    [DllImport("libuv", CallingConvention = CallingConvention.Cdecl)]
    Init原型如下:

  • public static extern int uv_tcp_init(UvLoopHandle loop, UvTcpHandle handle);
    Listen原型如下

  • public static extern int uv_listen(UvStreamHandle handle, int backlog, uv_connection_cb cb);
    Accept原型如下:

  • public static extern int uv_accept(UvStreamHandle server, UvStreamHandle client);
     

  •  

  • Init有重载方法,NetCore里面通过LivUV创建监听客户端的KeStrelServer,总共也就七步。完成了整个KeStrelServer的核心功能。(Java/.NET讨论群:676817308)
    ---------------------
    作者:tangyanzhi1111
    来源:CSDN
    原文:https://blog.csdn.net/tangyanzhi1111/article/details/85017252
    版权声明:本文为博主原创文章,转载请附上博文链接!

分类:

技术点:

相关文章: