中间件Middleware
中间件实现方式就是一层包一层的注册到一个集合中。
管道:处理http请求的不同的环节
- 浏览器发送请求
- DNS服务器解析域名,确定IP地址+Port(端口号)
- IP地址+Port就可以确定是哪一台服务—哪个一个程序来响应;服务器上运行的程序肯定是监听这某一个端口的;
- 确定到具体要响应请求的程序;程序如何响应?响应的过程就是请求处理的管道;
//这个方法就是用来配置如何处理Http请求;
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
- IApplicationBuilder:建造者模式,一定有一个地方来build一下,得到一个应用程序;
- 编写以下方法,会看到套娃式的输出结果。
Func<RequestDelegate, RequestDelegate> func01 = next =>
{
Console.WriteLine("this is middleware 01");
return new RequestDelegate(async context =>
{
await context.Response.WriteAsync("<h1>this is middleware 01 Start</h1>");
await next.Invoke(context);
await context.Response.WriteAsync("<h1>this is middleware 01 End</h1>");
});
};
app.Use(func01);
Func<RequestDelegate, RequestDelegate> func011 = next =>
{
Console.WriteLine("this is middleware 01.5");
return new RequestDelegate(async context =>
{
await context.Response.WriteAsync("<h1>this is middleware 1.5 Start</h1>");
await next.Invoke(context);
await context.Response.WriteAsync("<h1>this is middleware 1.5 End</h1>");
});
};
app.Use(func011);
Func<RequestDelegate, RequestDelegate> func02 = next =>
{
Console.WriteLine("this is middleware 02");
return new RequestDelegate(async context =>
{
await context.Response.WriteAsync("<h1>this is middleware 02 Start</h1>");
await next.Invoke(context);
await context.Response.WriteAsync("<h1>this is middleware 02 End</h1>");
});
};
app.Use(func02);
Func<RequestDelegate, RequestDelegate> func03 = next =>
{
Console.WriteLine("this is middleware 03");
return new RequestDelegate(async context =>
{
await context.Response.WriteAsync("<h1>this is middleware 03 Start</h1>");
//await next.Invoke(context);
await context.Response.WriteAsync("<h1>this is middleware 03 End</h1>");
});
};
app.Use(func03);
run
//Run终结式中间件---执行到这儿就不再往后继续了;
app.Run(async context =>
{
HttpResponse response = context.Response;
response.ContentType = "text/plain;charset=utf-8";
await response.WriteAsync("终结式。。。。");
});
//判断url中是否包含什么?
//判断路径--Url包含字符串,就执行后面的中间件
app.Map("/Richard", a => a.Run(async context =>
{
await context.Response.WriteAsync($"This is Advanced Richard Site");
}));
//接收两个委托,第一个委托参数当做条件,符合条件就执行下一个委托
app.MapWhen(context =>
{
return true;
//在这里已经拿到Httpcontex,就可以可以为所欲为;
//context.Request.Headers//1.判断是否是Ajax请求,如果是Ajax请求统一处理一下;
//基于Http协议的所有内容都可以拿到当做是否执行下一个调剂
}, build =>
{
//build.Use(new Func<RequestDelegate, RequestDelegate>());
});
自定义Run与Map
public static class CustomRichardMiddle
{
public static void CustomRun(this IApplicationBuilder builder, RequestDelegate handler)
{
Func<RequestDelegate, RequestDelegate> func = next =>
{
//next.Invoke();
return handler;
};
builder.Use(func);
}
public static void CustomMap(this IApplicationBuilder builder, string path, RequestDelegate handler)
{
//请求来了以后,可以判断Url中是否包含path,
Func<RequestDelegate, RequestDelegate> func = next =>
{
//next.Invoke();
return handler;
};
builder.Use(func);
}
}
Kestral服务器解析
Kestrel就是一个简化版IIS web服务器
负责监听请求—转发到代码—完成响应
Asp.NetCore本质是个控制台—运行起来是个网站—内置了一个Kestral(IIS服务器—所以来能脱离对IIS的依赖,所以才能做到跨平台)
有了kestrel,Asp.NetCore才能真正做到跨平台!
Kestral 配置
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)//
.ConfigureWebHostDefaults(webBuilder =>
{
#region MyRegion
//webBuilder.UseKestrel(o =>
//{
// o.Listen(IPAddress.Loopback, 10086);
//}).Configure(app => //配置监听到请求后转发给谁
//{
// //app.Run(async context => await context.Response.WriteAsync("Hello World123"));
// app.Run(context =>
// {
// //return Task.Run(() =>
// // {
// // //Console.WriteLine("Hello word。。。。。");
// // });
// return Task.Run(() =>
// {
// @delegate.Invoke(new CustomHttpContext());
// });
// });
//})
//.UseIIS()
//.UseIISIntegration();//支持IIS的集成模式
#endregion
#region MyRegion
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;//客户端最大连接数
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;//Websocket请求连接 不算数
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;//请求体积
serverOptions.Limits.MinRequestBodyDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));//请求正文最小数据速率请求传输速率
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);//默认值为 2 分钟。
serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);//请求标头所花费的最大时间量
}).Configure(app =>
{
//app.Run(async context => await context.Response.WriteAsync("Hello World123"));
app.Run(async context => await Task.Run(() =>
{
}));
});
#endregion
webBuilder.UseStartup<Startup>();
})
.ConfigureServices((context, sevice) =>
{
sevice.Configure<KestrelServerOptions>(context.Configuration.GetSection("Kestrel"));
});
}
管道模型
Http请求处理管道
Kestrel—MVC连接点