-
这几天发现,.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
版权声明:本文为博主原创文章,转载请附上博文链接!
相关文章: