previous Posts:
How to Implement UDP as a custom WCF transport (2)
How to Implement UDP as a custom WCF transport (1)
Adding a Binding Element
Now that the factories and channels are built,we must expose them to the ServiceModel runtime through a binding.
*** A binding is a collection of binding elements that represents the communication stack associated with a service address.
*** Each element in the stack is represented by a <binding> element.
It overrides the following methods to build the factories associated with our binding.
It also contains members for cloning the BindingElement and returning our scheme (soap.udp).
Note: In the sample, the binding element is UdpTransportBindingElement, which derives from TransportBindingElement ”An abstract base class that represents a transport binding element”.
It overrides the following methods to build the factories associated with our binding.
Note: You can use the binding element to configure different types of predefined bindings provided by Windows Communication Foundation (WCF).
public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
return (IChannelFactory<TChannel>)(object)new UdpChannelFactory(this, context);
}
public IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
return (IChannelListener<TChannel>)(object)new UdpChannelListener(this, context);
}
Adding Metadata Support for a Transport Binding Element
To integrate our transport into the metadata system, we must support both the import and export of policy.
This allows us to generate clients of our binding through the ServiceModel Metadata Utility Tool (Svcutil.exe).
Note:The ServiceModel Metadata Utility tool is used to generate service model code from metadata documents and metadata documents from service model code.
Remarks:The ServiceModel Metadata Utility Tool can be found at the Windows SDK installation location, specifically, C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin
Adding WSDL Support
The transport binding element in a binding is responsible for exporting and importing addressing information in metadata.
When using a SOAP binding, the transport binding element should also export a correct transport URI in metadata.
WSDL Export
To export addressing information the UdpTransportBindingElement implements the IWsdlExportExtension interface.
The ExportEndpoint method adds the correct addressing information to the WSDL port.
if (context.WsdlPort != null)
{AddAddressToWsdlPort(context.WsdlPort,
context.Endpoint.Address,
encodingBindingElement.MessageVersion.Addressing);}
The UdpTransportBindingElement implementation of the ExportEndpoint method also exports a transport URI when the endpoint uses a SOAP binding.
wsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);
if (soapBinding != null)
{
soapBinding.Transport = UdpPolicyStrings.UdpNamespace;
}
WSDL Import
To extend the WSDL import system to handle importing the addresses, we must add the following configuration to the configuration file for Svcutil.exe as shown in the Svcutil.exe.config file.
<configuration>
<system.serviceModel>
<client>
<metadata>
<wsdlImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter,
UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
When running Svcutil.exe, there are two options for getting Svcutil.exe to load the WSDL import extensions:
Point Svcutil.exe to our configuration file using the /SvcutilConfig:<file>.
-Add the configuration section to Svcutil.exe.config in the same directory as Svcutil.exe.
The UdpBindingElementImporter type implements the IWsdlImportExtension interface.
The ImportEndpoint method imports the address from the WSDL port.
BindingElementCollection bindingElements =
context.Endpoint.Binding.CreateBindingElements();
TransportBindingElement transportBindingElement =
bindingElements.Find<TransportBindingElement>();
if (transportBindingElement is UdpTransportBindingElement)
{
ImportAddress(context);
}
Adding Policy Support
The custom binding element can export policy assertions in the WSDL binding for a service endpoint to express the capabilities of that binding element.
Policy Export
The UdpTransportBindingElement type implements IPolicyExportExtension to add support for exporting policy.
As a result, System.ServiceModel.MetadataExporter includes UdpTransportBindingElement in the generation of policy for any binding that includes it.
In IPolicyExportExtension.ExportPolicy, we add an assertion for UDP and another assertion if we are in multicast mode. This is because multicast mode affects how the communication stack is constructed, and thus must be coordinated between both sides.
ICollection<XmlElement> bindingAssertions
= context.GetBindingAssertions();
XmlDocument xmlDocument = new XmlDocument();
bindingAssertions.Add(xmlDocument.CreateElement(UdpPolicyStrings.Prefix,
UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));
if (Multicast)
{
bindingAssertions.Add(xmlDocument.CreateElement(UdpPolicyStrings.Prefix,
UdpPolicyStrings.MulticastAssertion,
UdpPolicyStrings.UdpNamespace));
}
Because custom transport binding elements are responsible for handling addressing, the IPolicyExportExtension implementation on the UdpTransportBindingElement must also handle exporting the appropriate WS-Addressing policy assertions to indicate the version of WS-Addressing being used.
AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);
Policy Import
To extend the Policy Import system, we must add the following configuration to the configuration file for Svcutil.exe as shown in the Svcutil.exe.config file.
<configuration>
<system.serviceModel>
<client>
<metadata>
<policyImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
Note: Then we implement IPolicyImporterExtension from our registered class (UdpBindingElementImporter).
In ImportPolicy(), we look through the assertions in our namespace, and process the ones for generating the transport and check whether it is multicast.
We also must remove the assertions we handle from the list of binding assertions. Again, when running Svcutil.exe, there are two options for integration:
1-Point Svcutil.exe to our configuration file using the /SvcutilConfig:<file>.
2-Add the configuration section to Svcutil.exe.config in the same directory as Svcutil.exe.
Adding a Standard Binding
Our binding element can be used in the following two ways:
----Through a custom binding: A custom binding allows the user to create their own binding based on an arbitrary set of binding elements.
----By using a system-provided binding that includes our binding element.
WCF provides a number of these system-defined bindings, such as BasicHttpBinding, NetTcpBinding, and WsHttpBinding.
Each of these bindings is associated with a well-defined profile.
The sample implements profile binding in SampleProfileUdpBinding, which derives from Binding ”Contains the binding elements that specify the protocols, transports, and message encoders used for communication between clients and services.”
The SampleProfileUdpBinding contains up to four binding elements within it: UdpTransportBindingElement, TextMessageEncodingBindingElement CompositeDuplexBindingElement, and ReliableSessionBindingElement.
public override BindingElementCollection CreateBindingElements()
{
BindingElementCollection bindingElements = new BindingElementCollection();
if (ReliableSessionEnabled)
{
bindingElements.Add(session);
bindingElements.Add(compositeDuplex);
}
bindingElements.Add(encoding);
bindingElements.Add(transport);
return bindingElements.Clone();
}
Adding a Custom Standard Binding Importer
Svcutil.exe and the WsdlImporter type, by default, recognizes and imports system-defined bindings. Otherwise, the binding gets imported as a CustomBinding instance. To enable Svcutil.exe and the WsdlImporter to import the SampleProfileUdpBinding the UdpBindingElementImporter also acts as a custom standard binding importer.
A custom standard binding importer implements the ImportEndpoint method on the IWsdlImportExtension interface to examine the CustomBinding instance imported from metadata to see whether it could have been generated by a specific standard binding.
if (context.Endpoint.Binding is CustomBinding)
{
Binding binding;
if (transportBindingElement is UdpTransportBindingElement)
{
//if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the
//generated config file for better typed generation.
if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))
{
binding.Name = context.Endpoint.Binding.Name;
binding.Namespace = context.Endpoint.Binding.Namespace;
context.Endpoint.Binding = binding;
}
}
}
Generally, implementing a custom standard binding importer involves checking the properties of the imported binding elements to verify that only properties that could have been set by the standard binding have changed and all other properties are their defaults.
A basic strategy for implementing a standard binding importer is to create an instance of the standard binding, propagate the properties from the binding elements to the standard binding instance that the standard binding supports, and the compare the binding elements from the standard binding with the imported binding elements.
Adding Configuration Support
To expose our transport through configuration, we must implement two configuration sections.
The first is a BindingElementExtensionElement for UdpTransportBindingElement.
*** This is so that CustomBinding implementations can reference our binding element.
The second is a Configuration for our SampleProfileUdpBinding.
Binding Element Extension Element
The section UdpTransportElement is a BindingElementExtensionElement that exposes UdpTransportBindingElement to the configuration system.
With a few basic overrides, we define our configuration section name, the type of our binding element and how to create our binding element.
We can then register our extension section in a configuration file as shown in the following code.
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport />
</bindingElementExtensions>
</extensions>
</system.serviceModel>
</configuration>
<!--The extension can be referenced from custom bindings to use UDP as the transport.-->
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding configurationName="UdpCustomBinding">
<udpTransport/>
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
Binding Section
The section SampleProfileUdpBindingCollectionElement is a StandardBindingCollectionElement that exposes SampleProfileUdpBinding to the configuration system.
The bulk of the implementation is delegated to the SampleProfileUdpBindingConfigurationElement, which derives from StandardBindingElement.
The SampleProfileUdpBindingConfigurationElement has properties that correspond to the properties on SampleProfileUdpBinding, and functions to map from the ConfigurationElement binding.
Finally, override the OnApplyConfiguration method in our SampleProfileUdpBinding, as shown in the following sample code.
protected override void OnApplyConfiguration(string configurationName)
{
if (binding == null)
throw new ArgumentNullException("binding");
if (binding.GetType() != typeof(SampleProfileUdpBinding))
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
"Invalid type for binding. Expected type: {0}. Type passed in: {1}.",
typeof(SampleProfileUdpBinding).AssemblyQualifiedName,
binding.GetType().AssemblyQualifiedName));
}
SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;
udpBinding.OrderedSession = this.OrderedSession;
udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;
udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;
if (this.ClientBaseAddress != null)
udpBinding.ClientBaseAddress = ClientBaseAddress;
}
To register this handler with the configuration system, we add the following section to the relevant configuration file.
<configuration>
<configSections>
<sectionGroup name="system.serviceModel">
<sectionGroup name="bindings">
<section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport />
</sectionGroup>
</sectionGroup>
</configSections>
</configuration>
<!--It can then be referenced from the serviceModel configuration section.-->
<configuration>
<system.serviceModel>
<client>
<endpoint configurationName="calculator"
address="soap.udp://localhost:8001/"
bindingConfiguration="CalculatorServer"
binding="sampleProfileUdpBinding"
contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">
</endpoint>
</client>
</system.serviceModel>
</configuration>
*******************very hard subject I hope to every one just understand 10% because I understood just 2% of this article :):):)
the Next article will be a test example and code for using this sample transport.
next article ::How to Implement UDP as a custom WCF transport (4)
Click here Download Articles Images