This is the tenth post in the WCF 4.5 series. I started this series of posts 4 months ago when .NET 4.5 developer preview was announced; The Beta/RC/RTM version is still to come, but hopefully it will be available soon, and you will be able to use the new WCF 4.5 features in your projects.
Until now, I’ve shown new features in configuration easiness and hosting improvements. In this post and the next one, I will cover new transport features, starting with the support for the UDP transport.
Previous Posts
- What’s new in WCF 4.5? Let’s start with WCF configuration
- What’s new in WCF 4.5? A single WSDL file
- What’s new in WCF 4.5? Configuration tooltips and intellisense in config files
- What’s new in WCF 4.5? Configuration validations
- What’s new in WCF 4.5? Multiple authentication support on a single endpoint in IIS
- What’s new in WCF 4.5? Automatic HTTPS endpoint for IIS
- What’s new in WCF 4.5? BasicHttpsBinding
- What’s new in WCF 4.5? Changed default for ASP.NET compatibility mode
- What’s new in WCF 4.5? Improved streaming in IIS hosting
I’ve been teaching WCF for several years now, and almost every time I explain to people about the different types of bindings and supported transports, someone asks me if there is a built-in support for a UDP transport. Until now, my answer was “It isn’t supported out-of-the-box, but there is a UDP transport sample in the WCF/WF samples”. From now on, my new answer is “In WCF 4/3.5 there is a sample implementation, but it is now out-of-the-box in WCF 4.5”.
You can get some basic information about the binding in the System-Provided Bindings page on MSDN (make sure you look at the 4.5 version), unfortunately there is no documentation on the UdpBinding
type yet, but hopefully Microsoft will create it by the time WCF 4.5 is released.
Declaring an endpoint that uses UDP is quite simple:
<endpoint address="soap.udp://localhost:8080/"
binding="udpBinding" contract="UdpHost.IService" />
Some facts about the new UDP binding:
- The address scheme for this binding is
soap.udp://
- The binding is not interoperable (no kidding…)
- Security is not supported (neither transport or message)
- Sessions, transactions, streaming, and duplex are not supported (I was hoping for a duplex UDP using one-way messages)
- Supported encoding is text
- The binding can be used in code by adding a reference to the
System.ServiceModel.Channels
assembly - The binding is not supported in IIS/WAS, since there is still no UDP shared listener for WAS
- In the case of One-Way messages, this is a true one-way unidirectional call - the client won’t throw an exception if the service is unavailable
- If you specify a multicast address in the endpoint, such as 224.0.0.1 or 239.255.255.255 (the later is used by UDP discovery endpoints), you can create multiple listeners on the same address+protocol even from different machines – one client can send a single message that will be received by multiple listeners – this can be a great way to synchronize server state, do pub-sub (notification) calls, etc...
Using a multicast listening address is also quite simple:
<endpoint address="soap.udp://239.255.255.255:8083/"
binding="udpBinding" contract="UdpHost.IService" />
As for performance, I’ve created a simple client which sends 5000 messages using request-response and one-way (simple and multicast), with HTTP (basicHttp
), TCP, and UDP bindings. For the purpose of the test, I’ve removed all security settings from the NetTcp
binding. The result is shown below:
Calling 5000 iterations one way using UDP
One-way using UDP took 0 seconds, average is 0.1792ms
Calling 5000 iterations one way using HTTP
One-way using HTTP took 6 seconds, average is 1.3ms
Calling 5000 iterations one way using TCP
One-way using TCP took 2 seconds, average is 0.5876ms
Calling 5000 iterations one way using UDP Multicast
One-way using UDP Multicast took 3 seconds, average is 0.736ms
Calling 5000 iterations of request-response using UDP
Request-response using UDP took 7 seconds, average is 1.4738ms
Calling 5000 iterations of request-response using HTTP
Request-response using HTTP took 8 seconds, average is 1.7784ms
Calling 5000 iterations of request-response using TCP
Request-response using TCP took 4 seconds, average is 0.9518ms
Conclusions
- One-way messages are fast when using UDP – about 7 times faster than HTTP, and 3 times faster than TCP. I assume this is because when using UDP, we don’t need to wait for the TCP ACK (also used in HTTP).
- One-way multicast messages in UDP are slower than direct messages – about 4 times slower.
- Request-response message in UDP are slower than TCP, but faster than HTTP. I assume the reason for being slower than TCP is that UDP uses two channels to create request-response whereas TCP requires only one channel.
Trying to run the same sample when the server has not been started produces the following results:
Calling 5000 iterations one way using UDP
One-way using UDP took 0 seconds, average is 0.1216ms
Calling 5000 iterations one way using HTTP
One-way using HTTP failed
Calling 5000 iterations one way using TCP
One-way using TCP failed
Calling 5000 iterations one way using UDP Multicast
One-way using UDP Multicast took 1 seconds, average is 0.376ms
Calling 5000 iterations of request-response using UDP
Request-response using UDP failed
Calling 5000 iterations of request-response using HTTP
Request-response using HTTP failed
Calling 5000 iterations of request-response using TCP
Request-response using TCP failed
As you can see, UDP one-way messages are unidirectional!!!
The sample code is available on my SkyDrive.