Having a PollingDuplex service and any other WCF service in the same website causes Silverlight calls to be slow
After polling duplex support for WCF was released in Silverlight 2 (https://msdn.microsoft.com/en-us/library/dd470105(VS.95).aspx), some customers reported the issue that when a polling duplex service co-exists with normal WCF service on the same IIS web application, the WCF service might be significantly slowed sometimes.
In this post we will show you the process the team followed to resolve the issue. Hopefully you will find this useful in debugging your own SL apps when you encounter a problem. Please see the end of the post for the solution.
The first thing we have to do is to create some code that reproduces the issue. After contacting customers to get there scenarios and settings, we are able to create a test Silverlight application and ASP.Net web application that consistently reproduce this issue (see attached probject). Our test application has two client proxies, one polling duplex based stock ticker and one normal BasicHttpBinding-based calculator. Once the xap is loaded, calculator proxy will start continuously calling the “Add” method of the calculator. The app also has a checkbox which will cause the stock ticker service to start sending periodic stock price updates to the SL client, so at this point the SL all will be using both the regular WCF service and the polling duplex service.
By doing some research we identified that the following features could be influencing the observed slow behavior:
· Using WCF’s ASP.Net Compatibility Mode
· Using ASP.Net sessions
· Selecting between the Silverlight BrowserHttp or ClientHttp stack
We then ran a series of tests to determine when we could observe the slowness reported by our customers.
Browser Http |
Client Http |
|
ASP.Net compat mode enabled Session enabled. |
Slow |
Normal |
ASP.Net compat mode enabled Session disabled |
Normal |
Normal |
No ASP.Net compat |
Normal |
Normal |
As it shows above, the slowdown of the WCF call happens when the services are hosted in ASP.Net compat mode AND when user enabled ASP.Net sessions. The ASP.Net session is enabled when your web application has a global.asax file and it contains a session_start method. It turns out when the ASP.Net session state is enabled, requests for the same session will be processed sequentially. So the calls to the responses for the regular WCF service will get queued up behind the long polls made to the polling duplex service.
Using Fiddler, we can capture the HTTP packages and see the mechanism that ASP.Net uses to enable the session. It is enabled by setting the ASP.NET_SessionId cookie from service side.
POST /PollingWcfServices/ServiceWcf.svc HTTP/1.1
Accept: */*
Content-Length: 564
Content-Type: application/soap+xml; charset=utf-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0
Host: foo
Connection: Keep-Alive
Pragma: no-cache
Cookie: ASP.NET_SessionId=iyr4sf55rm1kypafjdvlhm55
This is why the client stack can work around the concurrent requests issue. By default when you use client stack, cookies are not automatically maintained between requests so the cookie set on the server is not returned in the subsequent request. Without the cookie ASP.Net doesn’t know which session to lock and it doesn’t lock it.
To work around the slowness, the user can switch to using the client stack to access both services. If the user wants to take advantage of ASP.Net sessions for the regular WCF service, they can use the browser stack for the regular service and the client stack for the polling duplex service. Currently the polling duplex service cannot be used with the browser stack if ASP.Net sessions are enabled. Here is the documentation page on how to register the browser or client stack for a given service.
All WCF services require read/write session state access if you enableASP.Net sessions, which causes the replies to be queued sequentially. Ideally user should be able configure the WCF handler to be read only, which would allow polling duplex services to work with sessions. Unfortunately this is unsupported at this point.
Instruction for running the sample
1. Run Visual Studio as administrator
2. Enable anonymous authentication on the web application created by the project
Comments
Anonymous
February 04, 2010
Hi ! Yeah, I claimed that a long time ago, with no feedback. Then I went to: http://stackoverflow.com/questions/1269198/how-to-force-an-iis-hosted-wcf-or-asmx-webservice-to-use-session-object-readonl I am back to use ashx now, which offers the right performance! --scambAnonymous
February 19, 2010
Hi, here is a workaround...it will work. http://koolsand.blogspot.com/2010/02/why-iis-hosted-wcf-services-does-not.html Thanks