Introduction to Windows Communication Foundation for the .NET Compact Framework Messaging Stack
This BLOG continues my discussion into new features of .NET Compact Framework 3.5 by diving into Windows Communication Foundation for the .NET Compact Framework Messaging stack. To start I suggest you read Romans WCF overview BLOG at https://blogs.msdn.com/romanbat/archive/2006/10/21/windows-communication-foundation-compact-edition-and-the-story-of-the-lunch-launcher.aspx
As with all features included in NETCF, the WCF implementation needed to be small to fit into device ROM's. Our original budget was 250kb and we tracked closely to this goal by cutting out the service layer and implementing a sub-set of the messaging stack. Throughout our investigation a few critical end to end solutions required messaging level security, which was not orrginaly planned for. To address these solutions, WCF for NETCF includes a subset of WS-Security. This drove our size up to ~450kb. The final implementation of WCF for NETCF includes the HTTP and email based transport, the text encoders and WS-Security. Each of these features are extensible and provides a flexible framework to allow each component to be swapped out or extended as needed.
To introduce the messaging stack lets look at a hello world example using HTTP or HTTPS request response. There are distinct tasks which need to be completed for the client solution which includes; create the message, create the channel, open the channel, send the message then receive the response. Server tasks follow similar steps; create the channel, open the channel and wait for response, parse and respond to the message. To demonstrate this type of messaging channel I've added a simple code example below. The client code will run on the PC so I if you do not have Orcas Beta1 or greater, which includes System.ServiceModel.dll, you can start your investigation PC them move to device when Orcas Beta2 is released. Lets look at the specifics of a simple hello world example.
I've updated the code below to reflect the changes found in Orcas Beta2.
Messaging Hello World Client Code:
The Hello World example below describes a simple use of the messaging stack in conjunction with the canned HTTP binding element.
We need to implement infrastructure used by both the client and server.
First we need to add the needed references.
First add references to:
1. System.ServiceModel.dll
2. System.XML.dll
3 System.Runtime.Serialization.dll
Next we add the using statements.
using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Channels; using System.Xml; using System.Xml.Serialization; using System.Runtime.Serialization;
Next we need serializable class to contain our data.
[System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(Namespace = "https://Microsoft.ServiceModel.Samples")] public class TransmittedObject { [System.Xml.Serialization.XmlElementAttribute(Order = 0)] public string str; [System.Xml.Serialization.XmlElementAttribute(Order = 1)] public int i; }
We next need to a helper class by extend the XMLSerilizer to be used in the context of WCF messages.
public sealed class XmlSerializerWrapper : XmlObjectSerializer { XmlSerializer serializer; string defaultNS; Type objectType; public XmlSerializerWrapper(Type type) : this(type, null, null) { } public XmlSerializerWrapper(Type type, string name, string ns) { this.objectType = type; if (!String.IsNullOrEmpty(ns)) { this.defaultNS = ns; this.serializer = new XmlSerializer(type, ns); } else { this.defaultNS = ""; this.serializer = new XmlSerializer(type); } } public override bool IsStartObject(XmlDictionaryReader reader) { throw new NotImplementedException(); } public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName) { throw new NotImplementedException(); } public override void WriteEndObject(XmlDictionaryWriter writer) { throw new NotImplementedException(); } public override void WriteObjectContent(XmlDictionaryWriter writer, object graph) { throw new NotImplementedException(); } public override void WriteStartObject(XmlDictionaryWriter writer, object graph) { throw new NotImplementedException(); } public override void WriteObject(XmlDictionaryWriter writer, object graph) { this.serializer.Serialize(writer, graph); } public override object ReadObject(XmlDictionaryReader reader) { string readersNS; readersNS = (String.IsNullOrEmpty(reader.NamespaceURI)) ? "" : reader.NamespaceURI; if (String.Compare(this.defaultNS, readersNS) != 0) { this.serializer = new XmlSerializer(this.objectType, readersNS); this.defaultNS = readersNS; } return (this.serializer.Deserialize(reader)); } }
We now have enough infrastructure to build the message. It can look something like:
TransmittedObject to = new TransmittedObject();
to.str = "Hello";
to.i = 5;
XmlSerializerWrapper wrapper =
new XmlSerializerWrapper(typeof(TransmittedObject));
Message m = Message.CreateMessage
(MessageVersion.Soap11, "urn:test", to, wrapper);
Next up we need to create the channel using the BasicHttpBinding.
BasicHttpBinding binding = new BasicHttpBinding();
BindingParameterCollection parameters =
new BindingParameterCollection();
IChannelFactory<IRequestChannel> channelFactory =
binding.BuildChannelFactory<IRequestChannel>(parameters);
channelFactory.Open();
The channel then needs to be opened. For PC to PC you can use LocalHost. If your using a device, you will need to setup an IIS server with an appropriate address which is reachable by the device
IRequestChannel outChannel =
channelFactory.CreateChannel
(new EndpointAddress(new Uri("https://<<ServerAddress>>:<<PortNumber>>")));
outChannel.Open(TimeSpan.MaxValue);
It time to send the message and wait for the reply
Message reply = outChannel.Request(m, TimeSpan.MaxValue);
Once the reply is received do Deserialize it and do something with the data.
TransmittedObject to1 =
reply.GetBody<TransmittedObject>
(new XmlSerializerWrapper(typeof(TransmittedObject)));
MessageBox.Show(to1.str + " " + to1.i.ToString());
Lets clean up
outChannel.Close();
channelFactory.Close();
Messaging Hello World Server Code:
Now lets look at what the server code could look like.
The server needs all the infrastructure described above including reference and using statements, TransmittedObject and XmlSerializerWrapper
Next the channel needs to be built.
BasicHttpBinding binding = new BasicHttpBinding();
BindingParameterCollection parameters =
new BindingParameterCollection();
IChannelListener<IReplyChannel> listener =
binding.BuildChannelListener<IReplyChannel>
(new Uri("https://<<ServerAddress>>:<<PortNumber>>"), parameters);
listener.Open();
XmlSerializerWrapper wrapper =
new XmlSerializerWrapper(typeof(TransmittedObject));
Next the channel needs to be opened.
IReplyChannel channel = listener.AcceptChannel();
channel.Open(TimeSpan.MaxValue);
Receiving the message
RequestContext r =
channel.ReceiveRequest(TimeSpan.MaxValue);
TransmittedObject to =
r.RequestMessage.GetBody<TransmittedObject>(wrapper);
Process the message
to.str = to.str + " World";
to.i = to.i + 1;
Finally we create the message and send the response.
Message m = Message.CreateMessage
(MessageVersion.Soap11, "urn:test", to, wrapper);
r.Reply(m, TimeSpan.MaxValue);
Lets Clean up
channel.Close();
I hope this provides a brief description of using the WCF messaging stack as its implemented for the device using the .NET Compact Framework.
Comments
Anonymous
March 26, 2007
Mark Prentice of the .NET Compact Framework team has just posted an introduction on how you will be ableAnonymous
March 26, 2007
Mark has a great post on the basics of WCF for the Compact Framework. Well worth the read! <<CheckAnonymous
March 26, 2007
Siguiendo la línea que os comentaba en el post anterior donde se mostraba un ejemplo que nos contaronAnonymous
March 27, 2007
Ecco che se ne inizia a parlare anche nella pratica . Ottimo! Tra una settimana sarò con RoB a completareAnonymous
March 27, 2007
Qualcosa inizia a muoversi ... ed era ora !!! Chissà che non riusciremo ad avere qualcosa per l'eventoAnonymous
March 27, 2007
Yesterday, Mark Prentice posted an introduction to the Windows Communication Foundation for .NET CompactAnonymous
March 27, 2007
Are you going to MEDC2007 in Las Vegas ? Marc Prentice is and he's started blogging about the new WCFAnonymous
April 03, 2007
Does this allow the Windows CE device to be the server part of the WCF equation? That would seem to be required for OEMs using Windows CE for custom platforms rather than the Windows Mobile application developers.Anonymous
April 05, 2007
While I was still an MS MVP and a_MS RD_, one of the things I have always requested is to have WCFAnonymous
April 11, 2007
Could you please provide some information related to supported channel shapes, custom behaviors and custom channels? How much of these powerful feature are you going to provide for CF?.Anonymous
April 14, 2007
The comment has been removedAnonymous
April 14, 2007
btw WCF on CF would really help a number of our projects. One Question if end to end security is not required - can you not load the security dll? Regards, BenAnonymous
April 25, 2007
Lets continue the discussion of the .NET Compact Framework new WCF features by discussing the new EMAILAnonymous
August 11, 2007
Lets continue the discussion of the .NET Compact Framework new WCF features by discussing the new EMAILAnonymous
September 07, 2007
Lately, I've been working on getting my WCF for NETCF hello world BLOG posts ( Intro to Messaging andAnonymous
September 07, 2007
Lately, I've been working on getting my WCF for NETCF hello world BLOG posts ( Intro to MessagingAnonymous
November 29, 2007
An Introduction to WCF for Device Developers Chris Tacke OpenNETCF Consulting, LLC November, 2007 DownloadAnonymous
March 20, 2009
MSDN文档 WindowsCommunicationFoundation(WCF)Developmentandthe.NETCompactFramework http://ms...