目录
HttpMessageHandler
Web Host模式处理过程
Self Host模式处理过程
HttpMessageHandler
Web API处理管道由一系列HttpMessageHandler组成
public abstract class HttpMessageHandler : IDisposable { protected internal abstract Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken); protected virtual void Dispose(bool disposing) public void Dispose() }
而一般在管道中,我们使用DelegatingHandler
public abstract class DelegatingHandler : HttpMessageHandler { public HttpMessageHandler InnerHandler { get; set; } protected internal override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return this.innerHandler.SendAsync(request, cancellationToken); } }
头部是HttpServer
public class HttpServer : DelegatingHandler { public HttpMessageHandler Dispatcher { get; } public HttpConfiguration Configuration { get; } protected virtual void Initialize() { this.InnerHandler = HttpClientFactory.CreatePipeline(this._dispatcher, (IEnumerable<DelegatingHandler>) this._configuration.MessageHandlers); } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { this.EnsureInitialized(); return await base.SendAsync(request, cancellationToken); } }
其中Dispatcher就是管道的尾部
默认为HttpRoutingDispatcher
public class HttpRoutingDispatcher : HttpMessageHandler { public HttpConfiguration Configuration { get; } private readonly HttpMessageInvoker _defaultInvoker = new HttpControllerDispatcher(configuration); public HttpRoutingDispatcher(HttpConfiguration configuration, HttpMessageHandler defaultHandler) protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { //1. Routing IHttpRouteData routeData = request.GetRouteData(); if (routeData == null) { routeData = this._configuration.Routes.GetRouteData(request); if (routeData != null) request.SetRouteData(routeData); } //2. Dispatcher this._defaultInvoker.SendAsync(request, cancellationToken); } }
实现Dispatcher(选择IHttpController)的对象默认为HttpControllerDispatcher
public class HttpControllerDispatcher : HttpMessageHandler { protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { HttpControllerDescriptor controllerDescriptor = this.ControllerSelector.SelectController(request); IHttpController controller = controllerDescriptor.CreateController(request); return await controller.ExecuteAsync(controllerContext, cancellationToken); } }
验证管道
public class DemoController : ApiController { public IEnumerable<string> Get() { var cfg = new HttpConfiguration(); cfg.MessageHandlers.Add(new Handler1()); cfg.MessageHandlers.Add(new Handler1()); cfg.MessageHandlers.Add(new Handler1()); var server = new MyServer(cfg); server.Initialize();//生成HttpMessageHandler链 return GetHandlers(server); } private IEnumerable<string> GetHandlers(MyServer server) { DelegatingHandler next = server; yield return next.ToString(); while (next.InnerHandler != null) { yield return next.InnerHandler.ToString(); next = next.InnerHandler as DelegatingHandler; if (next == null) break; } } } class MyServer : HttpServer { public MyServer(HttpConfiguration cfg) : base(cfg) { } public new void Initialize()//暴露Initialize方法 { base.Initialize(); } } class Handler1 : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { throw new NotImplementedException(); } }
浏览器中请求:
Web Host模式处理过程
上节我们说到HttpControllerHandler为Web Host下的处理程序.
public class HttpControllerHandler : HttpTaskAsyncHandler { private readonly HttpMessageInvoker _server = GlobalConfiguration.DefaultServer; public override Task ProcessRequestAsync(HttpContext context) { response = await this._server.SendAsync(request, cancellationToken); await response.Content.CopyToAsync(context.Response.OutputStream); } }
从上面的代码中我们看到
HttpControllerHandler实现的是异步HttpControllerHandler接口
在ProcessRequestAsync方法中 通过GlobalConfiguration.DefaultServer 启动了WebAPI管道
Self Host模式处理过程
Self Host目前可以说分为2种
- OWIN
- HttpBinding
本节重点说明一下传统方式的HttpBinding,WebAPI使用的Message为HttpMessage
通过Nuget可以非常方便的操作
Install-Package Microsoft.AspNet.WebApi.SelfHost
using (var server = new HttpSelfHostServer(new HttpSelfHostConfiguration("http://localhost:10000"))) { server.Configuration.Routes.MapHttpRoute("default", "{controller}"); server.OpenAsync(); Console.Read(); }
接下来我们将定义一个HttpSelfHostServer来实现SelfHost
API是不是相比SelfHost更方便?
using (var server = new MyHttpSelfHostServer("http://localhost:10000")) { server.Configuration.Routes.MapHttpRoute("default", "{controller}"); server.OpenAsync(); Console.Read(); }
再看看我们具体的MyHttpSelfHostServer如何实现
public class MyHttpSelfHostServer : HttpServer { private string _url; public MyHttpSelfHostServer(string url) { _url = url; } public async void OpenAsync() { var binding = new HttpBinding(); var listener = binding.BuildChannelListener<IReplyChannel>(new Uri(_url)); listener.Open();//开启监听 var reply = listener.AcceptChannel(); reply.Open();//开启通信通道 while (true) { var request = reply.ReceiveRequest();//接受到请求 //获取HttpRequestMessage var method = request.RequestMessage.GetType().GetMethod("GetHttpRequestMessage"); var requestMessage = method.Invoke(request.RequestMessage, new object[] { true }) as HttpRequestMessage; var response = await base.SendAsync(requestMessage, new CancellationTokenSource().Token); request.Reply(CreateMessage(response));//回复消息 } } Message CreateMessage(HttpResponseMessage response) { var type = Type.GetType("System.Web.Http.SelfHost.Channels.HttpMessage,System.Web.Http.SelfHost"); return (Message)Activator.CreateInstance(type, response); } }
最后我们来请求一下地址:http://localhost:10000/Demo
备注:
文章中的代码并非完整,一般是经过自己精简后的.
本篇内容使用MarkDown语法编辑
首发地址:http://neverc.cnblogs.com/p/5949974.html
来源:https://www.cnblogs.com/neverc/p/5949974.html