2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.ServiceModel / HTTP_listener_notes.txt
blobca668d6d22c630377a18ae4a59809e152e389218
1 * ASP.NET integration and HTTP standalone service process flow
3 This mostly explains what our WCF does, and does not explain what I think it really should do (though I write about them as long as I know).
6 ** Basic process flow
8 - ServiceHost opens a set of ChannelDispatchers for each ServiceEndpoint.
9 - ChannelDispatcher builds an IChannelListener (such as HttpSimpleChannelListener`1 or AspNetChannelListener`1) based on the corresponding ServiceEndpoint which contains a Binding that is used to build channel listeners).
10 - IChannelListener itself does not provide any service loop. Instead, the ChannelDispatcher starts a service loop.
11 -- IChannelListener only has methods for receiving requests that must be explicitly invoked for each request (i.e. to repeatedly process requests it must invoke receiver methods every time, unlike ServiceHost.Open() method).
12 - Inside the service loop, IChannelListener invokes [Begin]AcceptChannel() to get a channel such as HttpSimpleReplyChannel`1 or AspNetReplyChannel`1. Channels can be created as much as the service throttle limitation (ServiceThrottle) allows.
13 - Then the loop manager invokes the channel's [Begin]TryReceiveRequest().
14 - When WSDLs are enabled, ServiceMetadataExtension populates another ChannelDispatcher that serves HTTP requests to WSDLs.
15 -- It is important to understand that during this process it populates HTTP channel listener onto the same port and even possibly onto the same target URL, differentiating only by the request parameter (e.g. "?wsdl"). This causes a lot of confusion on both IHttpHandler (for ASP.NET) and HttpListener (for non-ASP.NET).
16 - Inside (abstract) HttpChannelListener`1, it internally has (abstract) HttpListenerManager which manages the actual HTTP listeners.
17 -- This intermediate stuff is required to manage HTTP listeners across the actual HttpChannelListeners because more than one channel listeners might use the identical HTTP listener; only one HttpListener can listen to a specific URI prefix, while (as explained above) WSDL support dispatcher may listen to the same URI only differentiating the query parameter.
20 ** non-ASP.NET-specific process flow
22 - HttpSimpleChannelListener`1 implements IChannelListener`1, HttpSimpleReplyChannel implements IReplyChannel`1, and HttpSimpleRequestContext extends RequestContext.
23 - HttpSimpleChannelListener`1 internally creates HttpSimpleListenerManager that manages HttpListeners. The management here includes sharing HttpListeners between the channel listeners that have the identical Uri (see WSDL section above).
24 - When HttpSimpleChannelListener`1.[Begin]TryReceiveRequest() is invoked, then it subsequently calls HttpListener.BeginGetContext() to retrieve the context.
27 ** ASP.NET-specific process flow
29 - An IHttpHandler manages one ServiceHost. IChannelListener is bound to a ChannelDispatcher. Hence, IChannelListener has a ServiceHost to which it is bound.
30 - HttpListener is designed to explicitly call [Begin]GetContext() method for each request processing. i.e. it is pull-based process.
31 - ASP.NET processing (IHttpHandler.ProcessRequest() method) is designed to be invoked by the ASP.NET runtime i.e. it is push-based process.
32 -- while WCF channels must be created by ChannelDispatcher, the ASP.NET channels must not be instantiated and returned immediately by IHttpHandler.ProcessRequest(), but have to wait for calls to IChannelListener.[Begin]AcceptChannel() at first.
33 -- Then, AspNetChannelListener`1 retrieves HttpContext. It has to wait for one if there is no HttpContext in the IHttpHandler)
34 -- Due to the process flow explained above, the IHttpHandler cannot handle the request when it receives a request. Instead, it has to store the HttpContext for IChannelListers' use.
35 -- Note that when there is WSDL extension, there is *another* IChannelListener that could be mapped to the identical URL i.e. which could be mapped to the identical IHttpHandler instance.
38 ** Call process flow and locking
40 - IHttpHandler.ProcessRequest()
41   - optionally create ServiceHost and
42   - calls ServiceHost.Open()
43   - ChannelDispatcher.StartLoop()
44   - AspNetChannelListener.[Begin]AcceptChannel() when throttling allows.
45   - AspNetReplyChannel.[Begin]TryReceiveRequest()
47 locking: TBD
50 ** Some notes
52 - WebHttpBinding creates HTTP channel listeners that share an identical endpoint URI, which could also be mapped by ServiceMetadataExtension. It brings problem on dispatching HTTP request to correct listener. FilterPriority is used to resolve the issue (possibly to some extent) that requests to wsdl/mex are treated in lower priority.
53 - While multiple channel dispatchers' endpoints could indicate an identical HTTP URI, it is not allowed to use the same HTTP URI across more than one ServiceHostBase and attempt to create such endpoints will result in InvalidOperationException for conflict with existing listeners.
56 ** Bugs
58 There is not a few bugs on service implementations and there often are reasons:
60 -- TCP duplex channels used to fail to serve requests when the throttle is 1. It was due to failure in managing closed channels (while it is duplex and hence it has to maintain channels until it is explicitly closed, clients often, or mostly, disconnects without any notice. So it had to be changed to explicitly check if the connection is available at any beginning of the request processing).
61 -- If there are more than one endpoint with the identical listen URI, it will fail to dispatch requests to correct listener even if the endpoints have appropriately configured FilterPriority. part of bug #573795.
62 - ASP.NET listener ends up to dump ThreadAbort during its shutdown. It's mostly harmless though.