摘要:WCF作为一个新的特征在.Net Compact Framework中得到实现。在中文MSDN的网站上,你可以找到很多相关的栏目都已经更新。其中有一些我在之前的文章中已经提及,本文将基于Exchange2007继续探讨WCF Compact特有的消息存储和转发特性(Store and Forward messaging)。
Keywords: WCF,Windows Mobile,.Net Compact Framework,Exchange Server 2007,Virtual Earth
(本文英文原文由marteaga发表于Opennetcf Community 原题为“Exchanging Data using Windows Mobile, Windows Communication Foundation, .NET Compact Framework and Exchange 2007”)
WCFMessagingManager
发送消息
WCFMessagingManager提供了下面的方法来使用Email的方式发送信息:
///<summary>
/// Sends a message to the receiving end
///</summary>
///<param name="recipient"></param>
///<param name="body"></param>
public void SendMessage(string recipient,string channel, T body)
{...}
SendMessage方法, 需要三个参数:
recipient, 是标识目标(收信方)Email地址
channel , 是目标所监听的信道
body ,是消息体对象. 注意这里的body是一个灵活的泛型对象.前面已经提及.
SendMessage的实现也是很直观的:
//使用channelfactory创建一个outputchannel
IOutputChannel outputChannel = m_channelFactory.CreateChannel(
new EndpointAddress(MailUriHelper.Create(channel, recipient)));
//打开信道
outputChannel.Open();
//创建待发送的消息对象
Message message = Message.CreateMessage(
MessageVersion.Default, UrnInternal,
body, m_xmlSerializerWrapper);
//发送消息
outputChannel.Send(message);
//关闭发送信道
outputChannel.Close();
消息发出后, 你会在收件箱中得到一条信息,并带有象下面这样的加密的标题
SM:v=3.5;CN=treochannel;ID=cbb5d3c798c84af3b1daf7615b780fb3;SD=633472436040000000;
实际上完整的消息是这样的:
<s:Envelopexmlns:a="http://www.w3.org/2005/08/addressing"xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Actions:mustUnderstand="1">urn:photoMessage</a:Action>
<a:Tos:mustUnderstand="1">net.mail://treochannel/#marteaga@opennetcf.com</a:To>
</s:Header>
<s:Body>
</s:Body>
</s:Envelope>
这段XML由System.ServiceModel.Channels.Message 自动创建.
在后面提到的PhotoData 对象中,下面的消息信息将会被添加到消息体"<body>"标签中。
<PhotoDataxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Id>9873fd22-189f-4525-97a5-4572dbcd7ad0</Id>
<FileName>/cf/200806/WCF Windows Mobile Exchange and NETCF_files/img002.jpg</FileName>
<Latitude>43.6919</Latitude>
<Longitude>-79.5782</Longitude>
<FileSize>6776</FileSize>
<Base64Data>...</Base64Data>
</PhotoData>
监听消息
WCFMessagingManager提供了一个BeginListening方法来启动一个单独的线程,在后台监听接收信息。 监听线程的主要实现方法如下:
//打开信道监听
m_channelListener.Open();
//接受并打开请求的信道
m_inputChannel = m_channelListener.AcceptChannel();
m_inputChannel.Open();
Message message;
//调用IInputChannel.Receive将会阻塞当前线程直至接收到一条信息
while (true)
{
message = m_inputChannel.Receive();
if (message == null)
break;
try
{
T body = message.GetBody<T>(m_xmlSerializerWrapper);
OnIncomingMessage(body);
}
catch (Exception e)
{
//调用异常处理
OnListenException(e);
}
}
这里我们首先打开了在WCFMessagingManager 构造器中创建的IChannelListener 。然后我们使用IChannelListener 创建了一个IInputChannel 。然后我们在一个while循环中调Receive()方法。
当接收到一条消息的时候,我们用GetBody来获取消息体对象(传入我们的XmlSerializerWrapper),并触发接收消息的事件处理程序。
WCFMessagingManager 还提供了StopListening()方法来停止监听,它将关闭所有通信信道和线程。