Tuesday, July 3, 2012

Net.TCP in Silverlight from IIS+WAS or ConsoleHost

Background
As usual a requirement came from onsite to one of the development team that they need to host WCF service using net.tcp and access the same from Silverlight 5. A developer spent couple of days but no luck. Then it came to me as I am serving as technical lead. First itself I raised the concerns on using net.tcp with Silverlight as Silverlight implementation lacks security features of net.tcp. Only advantage is the reduced payload size and speed. But there were no clear answer. So started debugging session to correct the sample.

There are so many articles and forum posts about the same with step by step explanation. But if we look closely at the comments, it says most of the people were not able to accomplish the task of setting net.tcp in IIS 7 and call the same from Silverlight. Also we were not able to find any good sample which does this. So planned to post the sample we used for net.tcp to Silverlight 5 communication which I think will help a lot of people.

Hosting net.tcp in IIS + WAS Host and accessing from Silverlight
I don't want to duplicate the contents here as you can get detailed steps with screen shots from the links given below. But would like to highlight the points which we noticed while doing the task.
  • Make sure you have enabled non-http activation in Add remove programs->Turn windows features on or off-> Microsoft .Net framework 3.5.1
  • Make sure the net tcp related listener and adapter services are running in Services.msc
  • The clientaccesspolicy.xml file should be present in the root of IIS with default port 80.
    • http://localhost/clientaccesspolicy.xml must be present regardless you are pointing to c:\inetpub\wwwroot\clientaccesspolicy.xml or some other path
    • The contents should be same as described in any of the links below. Main thing is the tcp port range 4502-4534.
  • The tcp port range which Silverlight supports for net.tcp communication is 4502-4534 .So your service need to use port number which comes in this range. Eg net.tcp://localhost:4503/
  • The port which you are using in the above step must be open in the firewall. Better switch off firewall if you are facing any issue.Once you get it running on firewall and add exception.
  • If you are hosting the services in "Default Web Site" of IIS make sure the edit site->bindings are pointed to the port numbers in the range 4502-4534. eg: 4504:*
  • If you are in Visual studio make sure you are using IIS for running WCF services. Create the IIS web application from Project properties->Web->Use  local IIS web server
  • Make sure the "Default Web Site" and web application in IIS has net.tcp in the enabled protocols section.
  • Turn off the security features of net.tcp in the web.config as Silverlight doesn't support the same .By default in .Net the tcp security will be on. Better make all the security related attribute in the netTcpBinding to "None".
  • A <clear/> tag is advised in the <Service> element in web.config before adding the end points.
  • Try to "Add Service Reference" using the net.tcp://site/service url itself. This will make sure that the server side is correct.
  • In ServiceReferences.ClientConfig use the CustomBinding and inside that binaryMessageEncoding & tcpTransport. There is no security related element in Silverlight config.
Hosting net.tcp  in ConsoleHost and accessing from Silverlight
This is another scenario which I tried along with hosting in IIS and though of sharing the same. Below are the points to note.
  • There is no need to run any additional exe as socket policy server which was there till Silverlight 4 beta.
  • While adding service reference you can use the mex url.eg:net.tcp://localhost:4503/mex
Challenges faced
  • We added the service reference with http:// url which worked fine.But when we tried to call using net.tcp url it failed. So always use net.tcp url to add service reference.
  • We tried to add some security related attributes in the ServiceReferences.clientconfig file which caused more errors. Leave it minimal.
  • There were some exceptions which we cannot catch in Visual Studio.Use the diagnostic trace listeners on System.ServiceModel so that debugging will be easier.For example the below one was never caught by VS
  • We were getting an exception at the server side (service svclog) that there is a protocol exception .We resolved it by making all the security related attributes of nettcpbinding to None. The exception was System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0."Stream Security is required at http://www.w3.org/2005/08/addressing/anonymous, but no security context was negotiated. This is likely caused by the remote endpoint missing a StreamSecurityBindingElement from its binding."
Running the attached sample

Download the sample and read the below points about the same.
  • WCFWASService project contains the WCF service .Make sure this web project is running using IIS.
  • ConsoleHost project contains a service which is exposed via net.tcp://localhost:4503/GetData .Goto the bin/debug folder of this project and double click on the ConsoleHost.exe to start the service.
  • SilverlightApplication1.Web is the web host for silverlight application.
  • SilverlightApplication1 is the Silverlight 4 app from which we are going to access the IIS hosted and Console hosted net.tcp services. The url to IIS hosted service is in the ServiceReferences.clientconfig file and the other is hard coded in the method Implementation.TestGetData()
  • If you want to add the service reference of ConsoleHost to any other app use the url net.tcp://localhost:4503/mex
Links which explains step by step
http://tomasz.janczuk.org/2009/11/pubsub-sample-with-wcf-nettcp-protocol.html
http://www.ditran.net/self-hosted-nettcp-wcf-silverlight-4
With screen shots - http://www.silverlightshow.net/items/WCF-NET.TCP-Protocol-in-Silverlight-4.aspx

4 comments:

Arshdeep Singh Virdi said...
This comment has been removed by the author.
Arshdeep Singh Virdi said...

Hi,

I wish I could have found you post before, it is quite helpful.

I have a working Chat Application using Silverlight 5, WPF and WCF (NET.TCP).

You can check it out here:
http://iconnect.arshdeep-virdi.com/web/

Thanks,
Arshdeep Virdi

Arshdeep Singh Virdi said...

Looks like you just posted it few days back. It couldn't have helped me though ;)

Would love to use the new feature in the upcoming windows server with my Chat Application.

Joymon said...

Happy to hear that somebody noticed it. I was in confusion to put this post or not as SL itself is getting outdated :-(

You have a nice blog..Keep rocking..