Welcome to MSDN Blogs Sign in | Join | Help

Introduction to the Windows Communication Foundation for the .NET Compact Framework, Store and Forward Messaging

Lets continue the discussion of the .NET Compact Framework new WCF features by discussing the new EMAIL transport for store and forward messaging.  This BLOG builds off my previous BLOG on WCF deliverables included in NETCF 3.5.  I suggest you read my previous BLOG  before reading this BLOG, I also suggest you read Roman's BLOG as background.  Let’s take a closer look at this new feature by describing some of the key features discuss a few best practices and look at a HelloWorld example.

The EMAIL transport permits device addressability so that messages can be sent to a device and messages from the device can be stored up and forwarded on the next synchronization.  This allows developers to create applications for devices in the field to communicate their data to a local store.  The data is then transferred using ActiveSync's Always Up to Date passing the data through Exchange 2007 directly to the data center.  For more information on AUDT see: http://www.microsoft.com/technet/prodtechnol/exchange/2003/autd.mspx.  This feature also allows data to be pushed from the data center down to one or more devices; previously this was not an easy task! 

This communication is one way, the device can send a message to the data center or the data center can send a message to the device.  Each listener is limited to a specific channel name and will block while waiting for a message to be delivered.  For this reason, we suggest you spin up a separate thread for each channel listener allowing the data from the thread to be processed as needed and not block the entire application.

Using the email local store to store messages, allows the device to reboot or the application to be restarted while not interrupting the flow of messages.  To address this type of message delivery, your program will need to use a stateless programming model.

The sample below is an iteration of the http hello world example from my previous post.  It demonstrates the new EMAIL transport features in an easy to read format  Use this sample to help you start your investigation into Store and Forward Messaging, do not copy and paste it into production code.  This code will only run with the new EMAIL transport which ships with the .NET Compact Framework v3.5 beta1 which is being released with Orcas Beta1.

Configuring Your PC to run the Store and Forward Messaging Hello World.

First you will need the Beta2 or later version or later of the next Visual Studio code named Orcas.  Check http://msdn2.microsoft.com/en-us/vstudio/default.aspx for the latest updates.

Next you will need the Windows Mobile 6.0 SDK as it includes the ActiveSync Always up to Date features used by the EMAIL transport on device to keep the inbox up to date, see: http://www.microsoft.com/windowsmobile/default.mspx

The EMAIL transport on the data center side will only run on Exchange 2007.  If you have an Exchange 2007 server running on your network you can skip this section.  The Exchange team has made a trial in VPC form available, its a quick place to start. See http://www.microsoft.com/exchange/default.mspx for more details.   Before you move on, I suggest you validate your connection to the new Exchange server by running Outlook Web Access (OWA) from your PC.

Next you need to provide your emulator with network capabilities.  (ActiveSync's Always up to Date Feature does not run when ActiveSycn is providing the network connection.) For more on enabling networking with the emulator see: http://blogs.msdn.com/anandba/archive/2007/03/13/networking-support-on-device-emulator-in-vista.aspx

Once you have the Emulator up and running, next you need to configure ActiveSync to communicate with your Exchange Server.  See the Connecting to an Exchange Server by Using a Phone or a Wireless Network at: http://www.microsoft.com/technet/solutionaccelerators/mobile/deploy/msfp_8.mspx

I've updated the code below to reflect the changes found in Orcas Beta2.

 Store and Forward Messaging Hello World, the Device:

To begin with, you will need to create a new Smart Device project in Orcas.  You can use the Windows Mobile 5.0 or 6.0 SDK.  I used WM 6.0 Professional.

To start you need to add a reference to the device EMAIl transport Microsoft.ServiceModel.Mail.dll and Microsoft.ServiceModel.Mail.WindowsMobile.dll

Next lets add the needed using statements.

using System.Runtime.Serialization; using Microsoft.ServiceModel.Channels.Mail; using Microsoft.ServiceModel.Channels.Mail.WindowsMobile; using System.ServiceModel; using System.ServiceModel.Channels; using System.Xml.Serialization; using System.Xml;

Lets now add the TransmittedObject and XmlSerializerWrapper class from the previous post.

[System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://Microsoft.ServiceModel.Samples")] public class TransmittedObject { [System.Xml.Serialization.XmlElementAttribute(Order = 0)] public string str; [System.Xml.Serialization.XmlElementAttribute(Order = 1)] public int i; }
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)); } }

Now we have enough information to build the message.

            TransmittedObject to = new TransmittedObject();
            to.str = "Hello";
            to.i = 5;

            XmlSerializerWrapper wrapper = 
                new XmlSerializerWrapper(typeof(TransmittedObject));

            Message m = Message.CreateMessage
                (MessageVersion.Default, "urn:test", to, wrapper);

Next let’s setup a few variables used in the rest of the program, the device and server e-mail addresses and the channel name.

string channelName = "StoreandFowardMessageHelloWorld"; string serverAddress = "ServerMailAddress@ExchangServer.com"; string clientAddress = "DeviceMailAddress@ExchangServer.com";

Let’s build the output channel and send the message to the server.

            WindowsMobileMailBinding binding = new WindowsMobileMailBinding();
            BindingParameterCollection parameters = new BindingParameterCollection();

            //Create and open the Channel Factory
            IChannelFactory<IOutputChannel> channelFactory =
                                            binding.BuildChannelFactory<IOutputChannel>(parameters);
            channelFactory.Open();
            IOutputChannel outChannel = channelFactory.CreateChannel(
                                new EndpointAddress(MailUriHelper.Create(channelName, serverAddress)));
            outChannel.Open();

 Time to send the message.

      outChannel.Send(m);

Now the message has been sent, we need to listen for the response.  The listener will block so I would suggest in your production code to run any listener on a separate thread.  For this example just place it below the sender.

            IChannelListener<IInputChannel> listner = binding.BuildChannelListener<IInputChannel>
                                      (MailUriHelper.CreateUri(channelName, clientAddress), parameters);

            listner.Open();

            IInputChannel inputChannel = listner.AcceptChannel();
            inputChannel.Open();

            Message reply = inputChannel.Receive();

Now that we have the responce, lets Deserialize it and present the results to the user.

            TransmittedObject to1 = 
                reply.GetBody<TransmittedObject>
                (new XmlSerializerWrapper(typeof(TransmittedObject)));

            MessageBox.Show(to1.str + " " + to1.i.ToString());

Finally lets clean up the EMAIL channel objects.

            outChannel.Close();
            channelFactory.Close();

            listner.Close();
            inputChannel.Close();
            binding.Close();

Store and Forward Messaging Hello World, the Server:

Let’s look at the code needed to respond to the devices requests.

Create a new Windows Console Application,

To start you need to add a reference to the device EMAIl transport Microsoft.ServiceModel.Mail.dll and Microsoft.ServiceModel.Channels.Mail.ExchangeWebService.dll

Next lets add the needed using statements.

using System.ServiceModel; using System.ServiceModel.Channels; using Microsoft.ServiceModel.Channels.Mail.ExchangeWebService; using Microsoft.ServiceModel.Channels.Mail; using System.Runtime.Serialization; using System.Xml; using System.Xml.Serialization;

We need the TransmittedObject and XmlSerializerWrapper class from the device code above, copy and paste that section to your new project.

Next let’s set a few global variables from the device project.

            string serverAddress = "ServerMailAddress@ExchangServer.com";
            string serverPWD = "MyPassword";
            string clientAddress = "DeviceMailAddress@ExchangServer.com";
            string exchageServerLocation = "http://ExchagneServer";

Let now create the listener, again the input channel will block so in your production code you should spin up a new thread for each listener.  In this sample as with the device sample we will place it in line. If you are using windows credentials just pass null value as the second argument to the ExchangeWebServiceMailBinding.

            ExchangeWebServiceMailBinding binding = new ExchangeWebServiceMailBinding(
                                            new Uri(exchageServerLocation),
                                            new System.Net.NetworkCredential(serverAddress, serverPWD));
            BindingParameterCollection parameters = new BindingParameterCollection();

            IChannelListener<IInputChannel> listner = binding.BuildChannelListener<IInputChannel>
                                                  (MailUriHelper.CreateUri(channelName, ""), parameters);
            listner.Open();
            IInputChannel inputChannel = listner.AcceptChannel();
            inputChannel.Open(TimeSpan.MaxValue);
            Console.WriteLine("Channel Open");
            Message reply = inputChannel.Receive(TimeSpan.MaxValue);
            Console.WriteLine("Message Received");
            XmlSerializerWrapper wrapper = new XmlSerializerWrapper(typeof(TransmittedObject));
            TransmittedObject to = reply.GetBody<TransmittedObject>(wrapper);

Processing the message.

            to.str = to.str + " World";
            to.i = to.i + 1;

            Console.WriteLine("Responce: " + to.str + " " + to.i.ToString());

Sending the response through an output channel.

            Message m = Message.CreateMessage(binding.MessageVersion, "urn:test", to, wrapper);

            IChannelFactory<IOutputChannel> channelFactory = binding.BuildChannelFactory<IOutputChannel>(parameters);

            channelFactory.Open();

            IOutputChannel outChannel = channelFactory.CreateChannel(new EndpointAddress(
                                                MailUriHelper.CreateUri(channelName, clientAddress)));
            outChannel.Open();

            Console.WriteLine("Out Channel Open");

            outChannel.Send(m);

            Console.WriteLine("Message Sent");

Finally lets clean up the EMAIL channel objects.

            outChannel.Close();
            channelFactory.Close();

            listner.Close();
            inputChannel.Close();
            binding.Close();

Time to give it a try, start the server first then run the client code to the emulator you configured to sync with your exchange server.

Published Wednesday, April 25, 2007 11:05 PM by MarkPrenticeMS

Comments

# &raquo; Introduction to the Windows Communication Foundation for the .NET &#8230;

# Mark Prentice Introduces Store and Forward Messaging in .NET Compact Framework v3.5

Yesterday, Mark posted a 'Hello World' example using the Store and Forward Messaging technology which

Thursday, April 26, 2007 2:11 PM by David Kline

# WCF via Carrier Pigeons

Earlier this year the .NET Compact Framework team announced that there was going to be an implementation

Friday, May 11, 2007 2:26 AM by Nick's .NET Travels

# re: Introduction to the Windows Communication Foundation for the .NET Compact Framework, Store and Forward Messaging

Hai Mark,

   I am using Orcus and framework3.5.yesterday i was try u r hello wrold program..i got 4 errors can u pls explain

detailed..

here is My errors:

The type or namespace name 'ServiceModel' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

C:\Documents and Settings\Admin\My Documents\Visual Studio Codename Orcas\Projects\SmartDeviceProject1\SmartDeviceProject1\Program.cs(9,17): error CS0234: The type or namespace name 'ServiceModel' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

C:\Documents and Settings\Admin\My Documents\Visual Studio Codename Orcas\Projects\SmartDeviceProject1\SmartDeviceProject1\Program.cs(10,14): error CS0234: The type or namespace name 'ServiceMode1' does not exist in the namespace 'System' (are you missing an assembly reference?)

C:\Documents and Settings\Admin\My Documents\Visual Studio Codename Orcas\Projects\SmartDeviceProject1\SmartDeviceProject1\Program.cs(11,14): error CS0234: The type or namespace name 'ServiceModel' does not exist in the namespace 'System' (are you missing an assembly reference?)

Compile complete -- 4 errors, 0 warnings

========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

Bye

bala..

 

Mark Prentice:  This issue is due to the build included in Orcas Beta1.  To fix this issue read my post on the subject at http://blogs.msdn.com/markprenticems/archive/2007/05/29/store-and-forward-channel-beta1-take-two.aspx

Friday, May 11, 2007 11:37 AM by Balaji

# re: Introduction to the Windows Communication Foundation for the .NET Compact Framework, Store and Forward Messaging

HAve added code to a new project in Orcas. All is well except for the following error:

Error 2 'Microsoft.ServiceModel.Channels.Mail.WindowsMobile.WindowsMobileMailBinding' does not contain a definition for 'BuildChannelFactory' and no extension method 'BuildChannelFactory' accepting a first argument of type 'Microsoft.ServiceModel.Channels.Mail.WindowsMobile.WindowsMobileMailBinding' could be found (are you missing a using directive or an assembly reference?) C:\Users\Nick Wood\Documents\Visual Studio Codename Orcas\Projects\SmartDeviceProject3\SmartDeviceProject3\Form1.cs 31

I have added all the references for the project and all the using statements. What else am I missing

I am trying this under windows mobile 5 sdk as I plan to roll our solution out to the 50+ devices that we have now all on mobile 5 and not upgradable.

Please help.

Regards

Nick

 

Mark Prentice:  This issue is due to the build included in Orcas Beta1.  To fix this issue read my post on the subject at http://blogs.msdn.com/markprenticems/archive/2007/05/29/store-and-forward-channel-beta1-take-two.aspx

Tuesday, May 22, 2007 4:27 AM by Nick Wood

# .NET Compact Framework 3.5 Redistributables

Anyone working with Visual Studio &quot;Orcas&quot; to build mobile applications should be aware that

Saturday, May 26, 2007 1:15 AM by Nick's .NET Travels

# The Journey of the Lunch Launcher: Part 1 - The origins of the 'lunch launcher'?

Several years ago, when I first joined the .NET Compact Framework team, we took some time (a week, if

Friday, September 07, 2007 6:44 PM by David Kline

# WCF for NETCF Beta2 Update

Lately, I've been working on getting my WCF for NETCF hello world BLOG posts ( Intro to Messaging and

Friday, September 07, 2007 7:12 PM by Mark Prentice

# WCF for NETCF Beta2 Update

Lately, I&#39;ve been working on getting my WCF for NETCF hello world BLOG posts ( Intro to Messaging

Friday, September 07, 2007 7:45 PM by Noticias externas

# You have Flaschenpost: WCF Store and Forward Messaging Demo-Video

Wer sich das neue .NET Compact Framework 3.5 schon einmal angeschaut hat, wird festgestellt haben, dass

Tuesday, September 25, 2007 7:07 AM by FrankPr's R@ndom Th0ughts
New Comments to this post are disabled
 
Page view tracker