Tuesday, June 10, 2008

Using UDP multicast channel in WCF

I recently needed to build a WCF UDP application as a proof of concept.

Sadly UDP is not among the channels bundled with the WCF, so I needed to put up something myself:

  • Downloaded the WCF technology samples, containing a UDP transport demo (there used to be a sample at the netfx3 site, but it's long-gone)
  • Copied the UDP transport sample project (from the folder \Extensibility\Transport\Udp\Cs\UdpTransport) into my solution
  • Added the extensions section to the config file to add the UDP support (config file coming up soon)
  • Added multicast="true" switch to the binding section
  • The address prefix is hardcoded in the UdpChannelHelpers.cs file, so if you like something other than "soap.udp" you need to edit the "Scheme" constant.
  • Since UDP is limited by a 64kb packet size, you may also want to use the GZipEncoder (found in \Extensibility\MessageEncoder\Compression\CS\GZipEncoder)

You need to remember that since this is multicast, the client is the one doing the transmitting while the service is a only a passive listener.


Client configuration:


<configuration>
<system.serviceModel>

<extensions>
<bindingElementExtensions>
<add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
</bindingElementExtensions>
<bindingExtensions>
<add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
</bindingExtensions>
</extensions>

<client>
<endpoint address="net.udp://225.225.0.1:2222/Observer/"
binding="customBinding"
bindingConfiguration="DatagramServer" contract="DataContracts.IObserver"
name="ClientService" />
</client>

<bindings>
<customBinding>
<binding name="DatagramServer">
<binaryMessageEncoding></binaryMessageEncoding>
<udpTransport multicast="true" />
</binding>
</customBinding>
</bindings>

</system.serviceModel>
</configuration>




Service configuration:


<configuration>
<system.serviceModel>

<extensions>
<bindingElementExtensions>
<add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
</bindingElementExtensions>
<bindingExtensions>
<add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
</bindingExtensions>
</extensions>

<services>
<service name="ObserverService.Observer">
<endpoint address="net.udp://225.225.0.1:2222/Observer/"
binding="customBinding"
bindingConfiguration="DatagramServer"
contract="DataContracts.IObserver" />
</service>
</services>
<bindings>
<customBinding>
<binding name="DatagramServer">
<binaryMessageEncoding></binaryMessageEncoding>
<udpTransport multicast="true" />
</binding>
</customBinding>
</bindings>
</system.serviceModel>

</configuration>

5 comments:

Anonymous said...

I am getting the following error, can you please guide me if you know anything about this.
"The scheme net.udp specified in address is not supported."

I am trying to send the message to udp server through a web service.

Thanks

Adi said...

I'm not 100% sure, but as far as I recall the actual URL prefix is not THAT important.
Did you try using "soap.udp" instead?

Anonymous said...

Did anyone tried adding message level security for the custom udp binding? if yes please let me know how you acheived it.

Anonymous said...

how about posting the solution so we can see!?

dotmad said...

Here are the source files I based the source code above on:

http://blogs.microsoft.co.il/files/folders/dotmad/entry529877.aspx

http://blogs.microsoft.co.il/files/folders/dotmad/entry529876.aspx