我们注意这里有个关键词Message,WCF的服务模型构建在这样的Messge对象上面。这样的一个Message对象以一种松散的形式描述了一个SOAP信封。它主要由两部分组成:消息体和一个可扩展的消息头集合。消息体是由应用程序定义的,而消息头是由对程序员相对透明的WCF的基础架构添加和处理的。这样的一个Message是WCF最核心也是最基本的组件。这就像经典的网络应用中,我们习惯以一个byte数组作为信息的基元一样。
用于移动设备的.NET Compact Framework 3.5 包含了WCF的一个子集,称作CompactWCF。运行在Windows Mobile设备上的WCF应用程序同样要遵循精简的原则。Microsoft的.NETCF团队最初对CompactWCF的预计是250kb的框架,他们做了大量的工作削减服务层以实现尽量精简的MessageStack。除了WCF的Message层面的东西,WCF for NETCF还包括了WS-Security的一个子集,这使得WCF forNETCF的框架达到了450kb。当然,最终版本的要比这个还要大一点,因为在这中间还集成了HTTP和Email的基础传输结构,还有文本编码器等组件,大是大了点,不过这些组件都是由可扩展的兼容性良好的框架支持。
Compact WCF允许移动设备上的应用程序通过WCF服务与桌面PC机(服务器)进行交互。目前暂不支持在移动设备上直接发布服务,设备端的应用程序通常扮演的是发出服务请求的客户端的角色。在信道的绑定行为上,目前.NETCF3.5预定义的仅支持BasicHttpBinding和WindowsMobileMailBinding两种方式:
1)BasicHttpBinding,从本质上来讲,基本和原来调用Web Service的方式一样,因为它支持在http下进行传统的C/S互操作,客户端只需发出一个服务请求并等待回应。
2)WindowsMobileMailBinding,这是一个Compact WCF中全新的通信方式,它使用Email作为消息传输的载体,提供了一个全双工的通讯信道,允许进行非可靠的双向异步通信。
一个典型Compact WCF服务的应用场景如下:
一个货车司机M受雇于A公司,他持有一台运行着WCF客户端程序的移动设备。这个WCF的客户端程序注册了运行在A公司某台服务器上的一个WCF服务,用于及时获得客户提货的订单。当客户需要提货的时候,A公司通过WCF服务给M发送一个消息,M将货物送到客户那里。这里WCF服务是以一种非可靠的方式向M发出的提货消息,不管M的状态是怎样,不管他是否准备好。而在这个流程中,M也不必经常主动从服务器获取这些信息,这正是目前用得比较广的基于Web Service的模型。
WCF是一个层次化的协议栈,消息对象的格式和传输方式是相对独立的,这意味着你可以自定义这两个方面的组件,并添加到你的WCF应用程序中来。.NET Compact Framework团队正是利用了WCF的这种可扩展性,开发了独特的Email WCF消息模式。
2.Lunch Launcher—你必须知道的故事
关于Compact WCF,在它背后有一个Lunch Launcher(午餐发起者)的故事,这个故事直接导致了EmailWCF的诞生。来自.NET Compact Framework团队的Roman Batoukov在他的文章:WindowsCommunication Foundation (Compact Edition) and the story of the LunchLauncher 中提到了这个故事。大意如下:
.NetCF团队的伙计们喜欢去附近的一些当地的餐馆吃午餐。大家习惯叫上几个朋友一同去那些熟悉的餐馆,但是这样有一点比较麻烦,就是大家不好协调。因为大家不一定都待在各自的办公室里,有可能去了别的办公室甚至是另一栋办公楼,这就需要通过打电话,发email等手段联系。另外,大家对目的地也经常意见不一,每次得商量好一会儿。
而同时,.NET CF团队几乎所有人都有一部Windows Mobile的设备,可以接入Wifi网络或者各个运营商提供的网络。于是他们设想,如果有一个应用程序能实现这样的功能就好了:
某人通过移动设备发出一个午餐的邀请,这个邀请里面列出了一些备选的餐馆,然后大家投票决定去哪里吃饭。当投票完成的时候,投票产生的最终的目的地会反馈给每一个成员,然后大家一同去那个目的地就行了。恩一个不错的想法。(原文请查看
http://www.blogs.msdn.com/romanbat)
不过这个想法有个很大的问题,就是各个设备的地址不好确定。通过移动运行商接入Internet的设备,被指派的IP地址是动态的,而通过WiFi连接的设备又经常因为NAT或者防火墙的缘故而不能直接访问到。所以在这样一些分散的移动设备之间建立一个稳定的连接是非常困难的。
我们再考虑这样一个更为实际的例子。一名员工在办公室里的时候,他持有的移动设备可能通过WiFi接入到Internet,当他走出办公楼,他的移动设备可能又切换到通过移动运营商提供的服务网络(如GPRS或者CDMA)。之后,这名员工可能又要进入另一栋办公楼,然后又介入了另一个WiFi网络。就在这个几分钟的行程中,他的移动设备的IP地址改变了三次。
像之前提到的“午餐发起者”这样的移动应用程序需要能将消息从一台设备发送到其他设备。这样看来,除非所有的移动设备使用VPN接入到你的本地网络或者稳定地接入到同一个WiFi共享网络,并且大家都使用静态IP,否则,想让你的应用程序总是能找到伙计们的移动设备是不可能实现的。不过还是有些办法可以解决确定设备地址的问题,只不过代价比较高,比如使用中间件技术或者设备每隔几分钟去连接服务器侦测是否已有消息处于等待装态。