Wednesday, November 18, 2009

Pub/sub sample with WCF net.tcp protocol in Silverlight 4

NOTE: Many people reading this post are really looking for a publish\subscribe solution for Silverlight to implement a web chat or a stock quote application for the browser, a multiplayer online game, or some form of a web based collaboration tool, among others. If that fits your profile, you may want to check out http://laharsub.codeplex.com. Laharsub is an open source pub\sub message server for web clients, including Silverlight. It aspires to address the needs of people like you, who are interested in the subject matter of this post as well as willing to contribute your scenarios and requirements by leaving a comment. Enjoy!

Microsoft Silverlight 4 Beta unveiled at PDC 2009 adds support for WCF net.tcp protocol. The protocol enables duplex communication (sending asynchronous messages from the server to the client), and greatly improves performance compared to HTTP polling duplex protocol in Silverlight 2 and 3. This article demonstrates the use of the net.tcp protocol in the context of a pub/sub Silverlight 4 application. I am starting with the pub/sub application I used to demonstrate duplex capabilities of the HTTP polling duplex protocol before, and explaining the steps necessary to extend it to leverage the net.tcp protocol.

The full Visual Studio 10 Beta 2 solution of this Silverlight 4 sample is available for download.

Once you get the sample running, you will be able to establish asynchronous communication based on a pub/sub architecture with a single WCF service in the backend and three kinds of browser-based clients: Silverlight client using the WCF net.tcp protocol, Silverlight client using the HTTP polling duplex protocol, and AJAX client using the HTTP polling duplex protocol.

For more in-depth look at net.tcp, check out the most recent post on WCF net.tcp in Silverlight 4.

Overview

At high level, these were the most interesting steps necessary to convert the HTTP polling duplex sample I described before to support WCF net.tcp protocol added in Silverlight 4:

  1. Get the necessary tools: Visual Studio 10 Beta2 and Silverlight 4 Tools for Visual Studio 10 Beta2.
  2. Add support for net.tcp to the WCF duplex service already exposed over the HTTP polling duplex protocol.
  3. Publish the service to IIS7.
  4. Enable net.tcp activation in IIS7.
  5. Enable net.tcp protocol in IIS7.
  6. Allow Silverlight applications to communicate over TCP.
  7. Update the WCF service proxy in the Silverlight 4 application.
  8. Run and enjoy the sample.

I will describe steps 2-8 in more detail next.

Adding net.tcp support to a WCF pub/sub service

The pub/sub sample for HTTP polling duplex came with a WCF duplex service implementing the pub/sub logic. Enabling net.tcp protocol support for this service does not require any changes in the application code, and can be accomplished by adding a new endpoint in the web.config file (additions highlighted in bold):

    <system.serviceModel>
        <extensions>
        <bindings>
            <pollingDuplexBinding>
                <binding name="PubSub" useTextEncoding="true"/>
            </pollingDuplexBinding>
            <netTcpBinding>
                <binding name="PubSub">
                    <security mode="None"/>
                </binding>
             </netTcpBinding>
        </bindings>
        <services>
            <service behaviorConfiguration="Microsoft.Samples.Silverlight.PollingDuplex.Service.PubSubServiceBehavior"
                               name="Microsoft.Samples.Silverlight.PollingDuplex.Service.PubSubService">
                <endpoint address="" binding="pollingDuplexBinding" bindingConfiguration="PubSub"
                                       contract="Microsoft.Samples.Silverlight.PollingDuplex.Service.IPubSub"/>
                <endpoint address="" binding="netTcpBinding" bindingConfiguration="PubSub"
                                       contract="Microsoft.Samples.Silverlight.PollingDuplex.Service.IPubSub"/>

                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>
    </system.serviceModel>

This change will add a new net.tcp endpoint to the existing WCF pub\sub service. The net.tcp endpoint will exist side by side with an endpoint based on the HTTP polling duplex protocol, enabling clients to communicate with the service over either of the protocols. Metadata exchange endpoint will enable automatic generation of a client proxy for either of the protocols.

Publishing in IIS7

The development web server built into Visual Studio 10 does not support the net.tcp protocol, so you will need to deploy the web application to IIS7 to run the sample. You can use the Publish feature available for web application projects in Visual Studio to deploy the new web application to IIS7. In this article I am assuming the service will be deployed to http://localhost/pubsub.

Next, you must make sure the web application is properly configured for accepting net.tcp connections.

Enable net.tcp activation in IIS7

One important feature of IIS is the ability to activate a web application when an HTTP request targeting this application is received. Similar feature exists in IIS7 for net.tcp requests, but it may not be enabled by default depending on your system configuration. To make sure the feature is enabled or to turn it on, go to Control Panel | Programs | Turn windows features on or off and make sure WCF non-http activation is enabled:

Enable non-http activation in Windows 7

If you are running Windows 2008 server, the same feature is available through Server Manager.

To find out if net.tcp activation is enabled on your machine, go to the command line and run the following command:

sc query NetTcpActivator

The output should indicate the local service is running.

Enable net.tcp protocol in IIS7

Web applications in IIS7 can be selective about the protocols they support. When you create a new web application using the Publish feature of Visual Studio 10, it is configured to support HTTP protocol only and must be explicitly configured to enable net.tcp traffic as well. This can be done through Internet Information Services Manager. Go to the web application you have created (localhost/pubsub), choose Manage Application | Advanced Settings, and make sure net.tcp protocol is listed in Enabled protocols:

Enable net.tcp protocol for a web application

Furthermore, the web site within which the web application resides must provide net.tcp protocol binding that allows connections using desired TCP port numbers. The sample uses TCP port 4502, so the binding specification must at minimum allow this port. Go to the web site containing your web application (usually the DefaultWebSite), choose Edit Bindings, and make sure the net.tcp binding allows port 4502:

II7 binding configuration for net.tcp

To verify the WCF service is set up to accept net.tcp connections, try navigating the to the service URL in the web browser (e.g. http://localhost/pubsub/PubSubService.svc). There should be no errors and the help page for the WCF service should be displayed.

Allow Silverlight applications to communicate over TCP

For a Silverlight application to create a TCP connection to a backend server, the server must explicitly allow such a connection (this is a measure to prevent cross-domain security exploits). This is done by exposing an XML policy file over HTTP at the root of the domain where the Silverlight application is hosted, as documented at Network Security Access Restrictions in Silverlight. This is the same policy file that is also used to allow cross-domain HTTP requests from Silverlight applications, but its content is augmented to add policy for TCP connections as well.

For example, to allow all Silverlight applications to open TCP connections on ports 4502-4530 to the machine, create a clientaccesspolicy.xml file with the following content and host at the root of the document directory of your IIS server (typically c:\inetpub\wwwroot):

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*" />
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true" />
        <socket-resource port="4502-4530" protocol="tcp" />
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

Open you web browser and navigate to http://localhost/clientaccesspolicy.xml to verify it will be accessible to Silverlight applications. The permit-all policy above allows unrestricted cross domain calls for both HTTP and TCP protocol over ports 4502-4530.

The section below is applicable to Silverlight 4 Beta. As of Silverlight 4 RC (and Silverlight 4 RTM), the socket policy for WCF clients using the net.tcp protocol is obtained over HTTP as opposed to TCP port 943 – please see the preceding paragraph.

For a Silverlight application to create a TCP connection to a backend server, the server must explicitly allow such a connection (this is a measure to prevent cross-domain security exploits). This is done by exposing a TCP socket policy over TCP port 943 as documented at Network Security Access Restrictions in Silverlight.

There is an online project template for Visual Studio 10 which makes this task simple by creating a windows console application serving a TCP socket policy file. The easiest way to add this project to a Visual Studio 10 solution is by searching for “silverlight tcp” in the online templates through the Add New Project dialog in Visual Studio 10:

Silverlight TCP Socket Policy online project template in Visual Studio 10

The default socket policy included in the project template allows all Silverlight applications to connect to ports 4502-4534, which is the entire range of ports available to Silverlight applications. The policy can be customized if necessary. You can also access the Silverlight TCP Socket Policy project template outside of Visual Studio

Remember to start the socket policy server application on the machine where the WCF service is hosted before running the Silverlight client!

Creating a service proxy to the WCF net.tcp pub/sub service

Creating a service proxy to a WCF net.tcp service is easy with the Add Service Reference feature of Visual Studio 10. The process is essentially the same as adding a service proxy to an HTTP based request/response or duplex service.

One feature the WCF net.tcp proxy offers beyond what HTTP polling duplex supports is integration with configuration file. During proxy generation, endpoint and binding information will be stored in the ServiceReferences.ClientConfig file, which enables the service address and other binding details to be controlled declaratively through config:

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

An instance of the proxy using net.tcp protocol can be created in code by referring to the named endpoint in the configuration file:

PubSubClient client = new PubSubClient("NetTcpBinding_IPubSub");

The same proxy class can be used with HTTP polling duplex protocol, but the binding and address must be provided in code (we are working on providing configuration support for HTTP polling duplex before Silverlight 4 release):

PubSubClient client = new PubSubClient(
    new PollingDuplexHttpBinding(),
    new EndpointAddress(new Uri(App.Current.Host.Source + "/../../PubSubService.svc")));

Running the pub/sub sample

I have described key steps necessary to develop and deploy a Silverlight 4 application using the new WCF net.tcp protocol. The full Visual Studio 10 Beta 2 solution of this Silverlight 4 sample is available for download. The sample contains a pub\sub WCF server exposed over two endpoints: one using the HTTP polling duplex binding available in Silverlight 2 and 3, and the other using the WCF net.tcp protocol newly supported in Silverlight 4. There are three types of clients:

  • A pub\sub Silverlight 4 client that offers a choice of HTTP polling duplex or net.tcp protocols.
  • A pub\sub AJAX client that communicates with the server using the HTTP polling duplex protocol.
  • A publisher Silverlight 4 client that offers a choice of HTTP polling duplex or net.tcp protocols.

So what does this sample demonstrate? You can have a Silverlight 4 publisher using net.tcp protocol to publish messages to a topic managed by a WCF pub\sub service, and three pub\sub clients consuming these notifications seamlessly using net.tcp or HTTP polling duplex in Silverlight, or HTTP polling duplex in AJAX. I have added a fragment of Dante’s Divine Comedy if you think publishing stock quotes is too boring.

Publisher client using WCF net.tcp in Silberlight 4 running in Chrome Pub\sub client using WCF net.tcp protocol in Silverlight 4 running in Internet Explorer

 Pub\sub client using WCF HTTP polling duplex protocol in Silverlight 4 running in Mozilla Firefox Pub\sub client using WCF HTTP polling duplex protocol in AJAX running in Internet Explorer

You can read more about the HTTP polling duplex and AJAX aspects of the sample in several of my previous posts. For more in-depth look at net.tcp, check out the most recent post on WCF net.tcp in Silverlight 4.

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.

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.