The Journey of the Lunch Launcher: Part 3 - Managing the Transport
Part 1 - The origins of the 'lunch launcher'
Part 2 - MEDC 2007
In the first two installments (linked above), I introduced the lunch launcher and talked about getting ready for its debut at MEDC 2007 in Las Vegas. Now it's time to start looking at how the .NET Compact Framework v3.5 Store and Forward Messaging feature makes this application possible.
At the heart of the lunch launcher are the Windows Communication Foundation channel pairs (input and output). You may ask 'what do you mean channel pairs, isn't the one channel that sends and receives'? Excellent question! The answer is no. The Store and Forward Messaging feature is built upon one-way communications channels (IInputChannel and IOutputChannel). This is necessary due to the nature of email as a transport. Email has, what I term, variable latency. By variable latency, I mean that once a message has been sent, the time it will take for it to be received cannot be determined. It may be received in a few seconds, a few hours, a few days or never depending on when and if the recipient checks their email. This leads to some very interesting challenges in writing applications which leverage Store and Forward Messaging. I plan on discussing these challenges in a future post (separate from this series).
Back to the topic at hand... How does the lunch launcher manage the transport? All objects required to send and receive messages, for all three of the lunch launcher channel pairs (invitations, replies and notifications) are contained in a TransportObjects class, as shown below. This example is taken directly from the MEDC 2007 demo project.
Please note that specific details of property implementation and object construction have been removed for space reasons and that the following disclaimer covers all examples contained herein.
//-----------------------------------------------------------------------//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A//PARTICULAR PURPOSE.//-----------------------------------------------------------------------/// <summary>/// Object to encapsulate and simplify working with /// Windows Communication Framework objects/// </summary>public class TransportObjects{ /// <summary> /// The binding used to create the channels /// </summary> public WindowsMobileMailBinding Binding { get; } /// <summary> /// The name of the input channel (ex: "MyServiceChannel") /// </summary> public String ChannelName { get; } /// <summary> /// The input channel /// </summary> public IInputChannel InputChannel { get; } /// <summary> /// The channel factory used to create output channels /// </summary> public IChannelFactory<IOutputChannel> OutputChannelFactory { get; }}
The application engine creates the TransportObjects object and then initialize them (create the necessary Windows Communication Foundation objects) by calling Initialize().
/// <summary>/// Initializes the Windows Communication Foundation objects/// </summary>public void Initialize(){ try { this.m_Binding = new WindowsMobileMailBinding(); this.m_Binding.AcceptExistingMessages = true; // create the binding parameters used by our channels BindingParameterCollection bpc = new BindingParameterCollection(); // NOTE: input channel gets the email address from the binding Uri inputChannelUri = MailUriHelper.CreateUri(this.m_ChannelName, "");
// create the input channel listener
IChannelListener<IInputChannel> listener =
this.m_Binding.BuildChannelListener<IInputChannel>(inputChannelUri, bpc);
listener.Open();
// create the input channel
this.m_InputChannel = listener.AcceptChannel();
this.m_InputChannel.Open();
// now that we have the input channel,
// it is safe to close the listener
listener.Close();
listener = null;
// create the output channel factory
this.m_OutputChannelFactory = this.m_Binding.BuildChannelFactory<IOutputChannel>(bpc);
this.m_OutputChannelFactory.Open();
}
catch
{
// initialization failed, make sure we cleanup
Uninitialize();
throw;
}
}
When the application engine is done with a channel pair (at shutdown) or if anything bad occurs (exception on initialization, for example) Uninitialize() is called.
/// <summary>/// Uninitializes and cleans up the Windows Communication Foundation objects/// </summary>public void Uninitialize(){ if(null != this.m_InputChannel) { this.m_InputChannel.Close(); this.m_InputChannel = null; } if(null != this.m_OutputChannelFactory) { this.m_OutputChannelFactory.Close(); this.m_OutputChannelFactory = null; } if(null != this.m_Binding) { this.m_Binding.Close(); this.m_Binding = null; }}
In the event that the application engine encounters a faulted state on the transport, recovery is performed by the Recover() method. Recover calls Uninitialize and Initialize. If both succeed, success is indicated by the method returning true. Upon a true return, the application logic continues to send and receive messages. A false return aborts the channel pair's functionality.
/// <summary>/// Recovers from a transport fault by uninitializing and reinitializing/// the Windows Communication Foundation objects/// </summary>/// <returns>/// True if recovery was successful, false otherwise/// </returns>public Boolean Recover(){ Boolean recovered; try { Uninitialize(); Initialize(); // successful recovery recovered = true; } catch { // unsuccessful recovery recovered = false; Uninitialize(); } return recovered;}
Take care,
-- DK
Disclaimer(s):
This posting is provided "AS IS" with no warranties, and confers no rights.
The information contained within this post is in relation to beta software. Any and all details are subject to change.
Comments
Anonymous
September 28, 2007
Part 1 - The origins of the 'lunch launcher' Part 2 - MEDC 2007 Part 3 - Managing the Transport LastAnonymous
September 28, 2007
Part 1 - The origins of the 'lunch launcher' Part 2 - MEDC 2007 Part 3 - Managing the TransportAnonymous
October 17, 2007
Part 1 - The origins of the 'lunch launcher' Part 2 - MEDC 2007 Part 3 - Managing the Transport PartAnonymous
November 12, 2007
Part 1 - The origins of the 'lunch launcher' Part 2 - MEDC 2007 Part 3 - Managing the Transport PartAnonymous
November 12, 2007
Over the past couple of months, I have been serializing my experiences in writing the Lunch LauncherAnonymous
November 12, 2007
Over the past couple of months, I have been serializing my experiences in writing the Lunch LauncherAnonymous
November 12, 2007
Part 1 - The origins of the 'lunch launcher' Part 2 - MEDC 2007 Part 3 - Managing the TransportAnonymous
November 13, 2007
David Kline from the NETCF team just published a an in-depth tour of his personal experience workingAnonymous
November 13, 2007
David Kline from the NETCF team just published a an in-depth tour of his personal experience workingAnonymous
November 14, 2007
来自 .NET Compact Framework 研发团队的 David Kline 将自己开发 Lunch Launcher 示例程序的亲身经历撰写为博客系列文章。深入分析了在 .NET Compact Framework 3.5 中支持的 Windows Communications Foundation (WCF) 邮件传输通道的编程。Anonymous
November 15, 2007
The Journey of the Lunch Launcher and Store and Forward MessagingAnonymous
June 03, 2008
It was a busy time last month for mobility guru Jim Wilson , what with two geekSpeaks in a row, but he