Wednesday, November 18, 2009

WCF net.tcp protocol in Silverlight 4

Microsoft Silverlight 4 Beta unveiled at PDC 2009 enables Silverlight clients to communicate with a Windows Communication Foundation (WCF) service using the net.tcp protocol. The key benefits of the net.tcp protocol are:

  • support for duplex communication with a simple to use programming model,
  • excellent performance,
  • good integration with the Add Service Reference feature of Visual Studio,
  • improved library factoring to help optimize the Silverlight application (XAP) size.

Practical use of the protocol is constrained to intranet environments where firewall configuration is controlled, since the net.tcp protocol is subject to the same TCP port limitations as any Silverlight application (only ports 4502-4534 can be accessed). In addition, the net.tcp protocol in Silverlight 4 does not support transport level security.

Duplex communication

WCF net.tcp protocol in Silverlight 4 addresses the same duplex communication scenario as the HTTP polling duplex protocol from Silverlight 2 and 3, while providing a major performance improvement and maintaining the same, simple to use event based programming model:

DuplexServiceClient client = new DuplexServiceClient("NetTcpBinding_DuplexService");
client.ResponseReceived += new EventHandler<ResponseReceivedEventArgs>(client_ResponseReceived);

Silverlight 3 applications that need to receive asynchronous data notifications from the server (the flagship example is stock quote updates) could choose between two technologies: WCF’s HTTP polling duplex protocol or direct use of System.Net.Socket. Between these two choices, WCF offers a much simpler to use, strongly typed programming model based on events and callback contracts, as well as a firewall friendly protocol. I have published an example of using the HTTP polling duplex protocol to implement a pub/sub application before.

With the WCF net.tcp support added in Silverlight 4, client applications can continue to benefit from the programming model usability while gaining a major performance benefit over HTTP polling duplex protocol. Migration of client applications already utilizing HTTP polling duplex protocol to use net.tcp should require minimal changes in the application code. In practice, only the choice of the binding when creating a service proxy is affected. Similarly, a duplex WCF service already exposed over HTTP polling duplex endpoint will only require a new endpoint based on the NetTcpBinding from .NET Framework. This change can typically be done in configuration without modifying the service code.

Performance

Performance of net.tcp protocol compared to HTTP polling duplex is the key reason to consider using the WCF net.tcp protocol in duplex communication scenarios. Most of the performance benefits of net.tcp protocol also apply to request/response messaging patterns. There are three major performance gains net.tcp offers compared to HTTP polling duplex:

  • increase in throughput (decrease in latency) of data notifications a client application can receive from the server,
  • increase in the maximum number of connected client the server can support concurrently,
  • bandwidth reduction.

Let’s first inspect the throughput. I have created a casual benchmark application (code of which is available here) in which the server is sending a predefined number of messages to a client (each message contains 5 strings), and the client measures the time it takes to receive them all. I measured and compared two implementation variants: in one the client receives messages from the server on the UI thread of the application, and in the other the client uses a worker thread instead. The chart below shows the result of the benchmark comparing the HTTP polling duplex protocol to net.tcp (client was running on a Dell Latitude E6400 laptop):

Throughput of net.tcp and HTTP polling duplex protocols in Silvrelight 4

Note the throughput scale is logarithmic. There are a few takeaways here:

  • Throughput of net.tcp on a worker thread of a Silverlight 4 application is 87,000% greater (that is 870 times faster) than HTTP polling duplex. Net.tcp protocol is using multiple worker threads to receive and dispatch messages from the server. The HTTP polling duplex protocol builds on top of the HTTP stack which in Silverlight 4 uses a single UI thread to receive  messages (even if the request has originated on a worker thread).
  • Throughput of net.tcp on a UI thread is 550% greater (that is 5.5x faster) than HTTP polling duplex. Net.tcp protocol streams consecutive messages to the client over an active TCP connection which does not involve per-message network roundtrip (HTTP request/response) required by the Silverlight 3 implementation of HTTP polling duplex.
  • Throughput of net.tcp on a worker thread is 16,330% greater (that is 163 times faster) than on the UI thread. Messages net.tcp received and dispatched on multiple threads are only processed sequentially on a single UI thread if the original request was made on the UI thread. This performance gain of the worker thread over the UI thread is a phenomenon I described in the context of the HTTP protocol before.

Let’s now have look at server scalability. There are two interesting aspects: how many concurrent clients can a single server maintain, and how does the protocol scale out. I have written an article about scalability of a single server HTTP polling duplex deployment before. I have also suggested ways the HTTP polling duplex protocol can scale out in a separate post. The chart below shows two data points comparing performance of the net.tcp and HTTP polling duplex protocol on a 3.5 GHz dual core machine with 2GB RAM (not a poster child of a server machine, but something we had handy) in a broadcast scenario (server sends identical messages to a large number of clients at fixed frequency):

Scalability of the net.tcp and HTTP polling duplex protocol in Silberlight 4

The data shows the same hardware can support more concurrent clients with the net.tcp protocol than HTTP polling duplex. At the same time, however, scale-out of the net.tcp protocol requires backend affinity for the duration of the TCP connection, while scale out of the HTTP polling duplex protocol can be accomplished without similar guarantee at the HTTP layer (as I described here).

Last aspect of performance to consider is network bandwidth. I don’t have concrete data to show here, but the size of a single HTTP request/response per message of the HTTP polling duplex protocol is clearly a loosing proposition to the .NET Framing Protocol used for streaming multiple messages over TCP in the net.tcp protocol.

Visual Studio integration

Net.tcp protocol is well integrated with the Add Service Reference feature in Visual Studio 10. A WCF service proxy to a WCF service exposed using the net.tcp binding can be easily generated for a Silverlight 4 client application. Net.tcp protocol comes with Silverlight configuration support (ServiceReferences.ClientConfig), so the details of the binding, including service address, can be changed without recompiling of the application:

<configuration>
    <system.serviceModel>
        <bindings>
            <customBinding>
                <binding name="NetTcpBinding_DuplexService">
                    <binaryMessageEncoding />
                    <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://localhost:4502/tcpperf/DuplexService.svc"
                binding="customBinding" bindingConfiguration="NetTcpBinding_DuplexService"
                contract="Proxy.DuplexService" name="NetTcpBinding_DuplexService" />
        </client>
    </system.serviceModel>
</configuration>

Proxy can be instantiated in code by referring to the named endpoint in Silverlight configuration:

DuplexServiceClient client = new DuplexServiceClient("NetTcpBinding_DuplexService");

Library factoring

WCF library layering in Silverlight 4 has been updated to allow application (XAP) size to be optimized given the protocols that are actually used:

Factoring of WCF libraries in Silverlight 4

Applications that utilize only request/response exchange patterns using WCF have all the required components available in Silverlight core. Applications that require duplex message exchange patterns must include the System.ServiceModel.Extensions.dll in the XAP, as well as one or both of System.ServiceModel.NetTcp.dll and System.ServiceModel.PollingDuplex.dll, depending on the protocol the application is using. System.ServiceModel.Extensions.dll contains functionality common for all duplex communication scenarios. System.ServiceModel.NetTcp.dll supports the WCF net.tcp protocol, and System.ServiceModel.PollingDuplex.dll the HTTP polling duplex protocol.

When a proxy is created in a Silverlight 4 project using the Add Service Reference feature of Visual Studio 10, appropriate library references will be added to the project depending on the actual protocols the WCF service exposes.

Limitations

The WCF net.tcp protocol in the Silverlight environment has limitations that make it a better fit for some applications than others:

  • The protocol builds on top of Silverlight’s System.Net.Socket implementation and as such is subject to the same network security restrictions. In particular, a Silverlight application can only use TCP ports in the range 4502-4534. In practice it means the protocol is intended for use on intranets (as opposed to the public internet) as it requires environments where firewall configuration can be controlled.
  • Servers hosting WCF net.tcp services intended for consumption from Silverlight must also expose a socket policy to allow TCP connections from Silverlight clients. I have created an online project template for Visual Studio 10 to facilitate hosting of the TCP socket policy.
  • Net.tcp protocol in Silverlight does not support transport level security (i.e. it does not offer SSL protection). As such its use is limited to applications where security is not a requirement or the desired level of security is inherent in the environment the application is running in.

Summary

WCF net.tcp protocol in Silverlight 4 is a great fit for intranet applications that require the utmost in communication performance. The protocol supports the simple to use, event-based WCF duplex programming model. Adding strongly typed service proxy to a Silverlight project is made easy with integration with the Visual Studio 10 Add Service Reference feature. Communication and security limitations make the protocol a better fit for controlled intranet environments than the public internet. A good protocol alternative for a duplex communication for the public internet is the HTTP polling duplex already present in Silverlight since version 2.

44 comments:

  1. Wow, interesting data. Do you have numbers for a OSX-based client?

    ReplyDelete
  2. shame about the lack of security

    ReplyDelete
  3. Is message-level security supported even though transport-level isn't?

    ReplyDelete
  4. So is this a "proper" duplex communication channel as opposed to polling duplex?

    ReplyDelete
  5. Where are these assemblies?

    ReplyDelete
  6. We realize lack of transport level security is a major drawback in the current implementation of net.tcp and we consider this an important feature to add going forward.

    Silverlight does not currently support message protection (integrity and confidentiality) using WS-Security mechanisms. The only WS-Security feature supported by WCF in Silverlight is attaching basic username/password credentials to a message. However, such configuration requires transport level security. Given that net.tcp does not provide transport level security, basic credentials in WCF can only be added to messages sent over the HTTPS protocol.

    There is no single "proper" duplex communication channel in Silverlight, the choice depends on the requirements. Net.tcp offers performance far superior to HTTP polling duplex; at the same time its practical use is restricted to intranets due to TCP port range limitation and lack of transport level security. Going forward we plan to invest in adding SSL security to net.tcp as well as improving HTTP polling duplex performance.

    The System.ServiceModel.Extensions.dll and System.ServiceModel.NetTcp.dll are Silverlight extension assemblies and ship as part of Silverlight 4 SDK. They are typically located in "%Program Files%\Microsoft SDKs\Silverlight\v4.0\Libraries\Client" directory.

    ReplyDelete
  7. Hi

    The Visual Studio 2010 integration is failing. When I try to reference a tcp service in a SL 4.0 application, a message saying that there is no endpoints compatible with SL 3.

    I uninstalled the SL 3 SDK before install 4.0, and the problem continues happening.

    ReplyDelete
  8. Anonymous, how is the net.tcp binding configured on the service? In particular, is security turned off? The binding should look similar to this:

    <netTcpBinding>
    <binding name="PubSub">
    <security mode="None"/>
    </binding>
    </netTcpBinding>

    ReplyDelete
  9. Fantastic article Tomasz! I greatly appreciate the performance metrics. Instead of theorizing you actually quantify and compare performance. Thank-you. -Shaun

    ReplyDelete
  10. Is there any plan to remove port restrictions in near future??

    ReplyDelete
  11. Falguni, there are no plans to remove port restrictions in the near future. The restrictions have been put in place for security reasons. Aaron Oneal has a great write-up about the rationale of the port restrictions at http://blogs.msdn.com/ncl/archive/2009/06/23/why-does-silverlight-have-a-restricted-port-range-for-sockets.aspx. What is your scenario that requires access to a port outside of this range?

    ReplyDelete
  12. I don't understand the intranet and firewall requirements.

    If I build and deploy a WCF server that uses the required port range, and then deploy on a public web site a silverlight 4 app that talks to the WCF server, then are you saying that no one will be able to hit the service without messing with their firewall?

    Is it their windows firewall on their own computer or is it their home routers or does it have something to do with NAT (Network Address Translation)? Why wouldn't the silverlight app be able to initiate a duplex tcp connection with the server like anything else?

    ReplyDelete
  13. It is not as much a requirement as a restriction imposed by typical environments at the internet scale. If you deploy a service that accepts TCP connections in the specified port range, the firewall of your server and the network it is connected to (e.g. your company's network) must explicitly allow incoming connections on these ports. Next, client side environment must be configured to allow outgoing connections on this port, which in a general internet case is not a property that can be assumed as a default. If the default client configuration does not allow outgoing connections, client's must be aware of the limitation, knowledgeable and able to change it, and above all willing to do so, none of which can be safely assumed about an average user of the public internet. As such, the deployment of net.tcp based services is in practice limited to networks that are more tightly controlled.

    ReplyDelete
  14. Hey Tomasz,
    I'm assuming net.tcp is still held to the same cross-domain policy concerns as HTTP in Silverlight?

    P.S. - Can't you guys just sneak 808 in there ;)

    ReplyDelete
  15. Yes, net.tcp is subject to the same cross-domain security concerns as http, with the mitigation being the cross-domain policy file. Is there anthing specific you would want to do over port 808?

    ReplyDelete
  16. Would the net.tcp duplex for Sl4 work in the following scenario?

    - Intranet with necessary ports opened
    - WCF services layer on redundant servers behind NLB without a guarantee of backend affinity
    - Subscriptions kept in Distributed Cache (Velocity)


    When a server goes down what happens as the connection is made to another server through NLB?

    ReplyDelete
  17. SCollard, a net.tcp WCF channel maps to a single underlying TCP connection. This means that messages client sends over an instance of a net.tcp WCF channel will always reach the same instance of the backend service despite there being an NLB between them. If the net.tcp WCF channel instance is closed or faulted and subsequently recreated by the client, a different backend server may be used to serve the client in the absence of NLB affinity. So the key question is whether your application requires or relies on client affinity to any resources maintained by the server side with lifetime exceeding the lifetime of a net.tcp WCF channel. If you are building a pub\sub system, the question translates to whether your subscriptions are durable or not. If the answer is yes, you may have to look at mechanisms to share the durable state across backends, and Velocity is one technology that can speed it up.

    ReplyDelete
  18. So if I want to deploy a Silverlight 4 app which wants to take advantage of a duplex wcf service over the web, I would need to expose the wcf service through a PollingDuplexHttpBinding endpoint? (because I cannot rely that everyone has the tcp outgoing port allowed - 4502-4534)

    ReplyDelete
  19. Florin, you are right - polling duplex protocol is the way to go on the public internet.

    ReplyDelete
  20. Is it possible to have data validation attributes in the classes on the server side and when adding a service reference to the server to have the classes generated with the data annotations on them?

    ReplyDelete
  21. A cross-platform communications protocol that supports real call-backs and that works across the Internet and firewalls is ICE (http://zeroc.com).

    They have Silverlight 2/3 support as well.

    ReplyDelete
  22. Tomasz, is there any reason an approach like this wouldn't work?

    - On the server, expose your WCF service using both Net.TCP and PollingDuplexHttpBinding.
    - On the client, try to open a connection to the web service using Net.TCP.
    - If that succeeds, use Net.TCP.
    - If that fails, fallback to the PollingDuplexHttpBinding.

    That's the approach we're currently taking, and it seems to be working. Any reason why it wouldn't, or any reason why we shouldn't?

    ReplyDelete
  23. Ken, generally this seems like a great approach to me. One aspect to pay attention to are some behavioral differences between proxies that use net.tcp vs polling duplex that may or may not be relevant to how your application functions. For example, polling duplex will use TCP connections out of the browser enforced connection limit, while net.tcp will not. There are also differences in how net.tcp and polling duplex channels are faulted in case of a communication error.

    ReplyDelete
  24. Tomasz,

    Where is your online project template for Visual Studio 10 to facilitate hosting of the TCP socket policy? Seems that the link is broken

    ReplyDelete
  25. Is tcp.net going to be available on the Phone 7 implementation of Silverlight?

    ReplyDelete
  26. Net.tcp protocol is not going to be available on the Phone 7 platform.

    ReplyDelete
  27. Tomek -- will Net.TCP *ever* be available? Or just not right away? As I recall, the current WP7 version of Silverlight is a branch of Silverlight V3, but presumably future versions will be based on V4 (or V5), and hence would presumably have the new features...right?

    ReplyDelete
  28. As far as I know there was only time and resources that prevented net.tcp from being in WP7 - we are looking at adding this functionality in future releases. It would help if you could share more details about the kind of application that would benefit from net.tcp on the Phone platform.

    ReplyDelete
  29. Nothing solid at this point. But it makes sense, right, that (especially) on a wireless system, you'd want the fastest, least chatty protocol available, right?

    ReplyDelete
  30. On the other hand, battery power is oftentimes the limiting factor for application design on mobile devices, and to that end keeping an open TCP connection puts a strain on the battery.

    ReplyDelete
  31. Good point. But if you're going to be doing the sort of application that would reasonably require HTTP Polling Duplex (say, a mobile version of the collaboration app we're working on), it seems like keeping the Long Poll open would be maybe even harder on the battery. (Haven't tested it, obviously, and you know the internal details about 100x better than I do. :-)

    ReplyDelete
  32. You are correct, HTTP long polling is not a good choice for enabling asynchronous notifications from the server on a mobile device, as battery power consumption impact would be very similar to keeping an open TCP connection. In fact mobile devices are sufficiently different in that respect to warrant their own solution. On Windows Phone 7 one should consider using Push Notifications instead. A good post by Nick Harris on the topic is at http://www.nickharris.net/tag/how-to-receive-microsoft-push-notification/.

    ReplyDelete
  33. Hey There,

    I'm keen on building a cross web browser/Windows Mobile 7 MMO using silverlight, however I found that the TCPClient which exists in regular C# is no where to be found in silverlight. I was wondering if there was an alternative I could use which would work in silverlight for both windows mobile 7 and PC/Mac?

    Cheers

    ReplyDelete
  34. Im interested in the reason for restricting the net.tcp so effectivly it only work is usable for Intranets.
    It seems far superior to Http polling, and the restriction must have been added for a reason- or am I missing something?

    ReplyDelete
  35. Lex, the net.tcp support in Silverlight is subject to the same port restrictions as System.Net.Sockets. Rationale for the restrictions is outlined at http://msdn.microsoft.com/en-us/library/cc645032(VS.95).aspx.

    ReplyDelete
  36. Ahmed, the Windows Mobile 7 does not support TCP in this release. In Silverlight, there is no TcpClient, but you can use System.Net.Socket directly, or use WCF net.tcp binding.

    ReplyDelete
  37. i hope your team improve performance for http-duplex-polling in next version of silverlight. Because with now performance, it not value for use in real scenario.

    ReplyDelete
  38. When I used to write an HTTP polling duplex application to allow clients to stay up to date information from MSSQL in a period of time, the system almost always crashes after a few times to browse, or speed will become increasingly slow - not even always updated. I really feel the HTTP polling duplex is not a good solution if it's too bad performance like this.
    So, hope you have a better solution for the HTTP polling duplex in a near future to come.

    ReplyDelete
  39. We also had a hard time getting the HTTP Polling Duplex protocol to work reliably for us. We spent a lot of time troubleshooting strange, nonreproducible errors. Things got much, much better when we switched over to Net.TCP.

    ReplyDelete
  40. I am not sure what your message exchange pattern is, but you may want to check out http://laharsub.codeplex.com for an open source pub\sub solution that uses HTTP long polling and supports Silverlight, JavaScript (jQuery) and .NET as clients.

    ReplyDelete
  41. WCF is slow with comparison to raw socket
    http://www.udaparts.com/document/articles/fastsocketpro.htm

    ReplyDelete
  42. Hi,

    If you are using IIS and NET.TCP binding, then you need to add an exception in the windows firewall for the port that you are using on the machine where the service is running. Also you need to place the clientaccesspolicy.xml to the root folder and it will work.

    You can check my WPF and Silverlight 5 Chat Appliaction(partially complete) at:
    http://iconnect.arshdeep-virdi.com/web

    This application is using NET.TCP binding to connect to the WCF service. Also you can download the fully functional WPF client for testing.

    Regards,
    Arsh

    ReplyDelete
  43. This comment has been removed by the author.

    ReplyDelete
  44. Can somebody provide me an Example of NET.TCP binding with duplex communication.
    By hosting it in windows service

    ReplyDelete

My Photo
My name is Tomasz Janczuk. I am currently working on my own venture - Mobile Chapters (http://mobilechapters.com). Formerly at Microsoft (12 years), focusing on node.js, JavaScript, Windows Azure, and .NET Framework.