在.Net Micro Framework中使用DPWS

在.Net Micro Framework中使用DPWS

by Freesc Huang

http://fox23.cnblogs.com/

摘要:DPWSWindows Rally技术的一个子集, 主要用于在可接入网络的设备上提供对Web Service的支持. 本文介绍了DPWS及其在.Net Micro Framework v3.0上的支持库, 以及如何利用Visual Studio 2008 sp1.Net Micro FrameworkDevice上创建DPWShostclient, 并让它们在Windows Vista下得以运行.

关键词: DPWS, .Net Micro Framework, Web Service, Windows Vista

 

1.       什么是DPWS ?

DPWS, Device Profile for Web Services, 它定义了在资源有限的终端上使用的, 用于实现安全的Web service的最小接口集. Windows Vista上内置了DPWS的客户端类库(WSDAPI), 那些支持DPWS的设备(比如常见的某些支持DPWS的打印机)会自动出现在Windows VistaNetwork Explorer, 一如Windows XP可以发现UPnP的设备一样. 从某种程度上说, DPWSUPnPWeb Service实现. DWPS的架构如图所示:

 

Tips更多关于DPWS的内容请参阅DPWS的手册, 你可以在以下链接下载: http://schemas.xmlsoap.org/ws/2006/02/devprof/

 

2.       .Net Micro Framework上的DPWS类库

DPWS Host类库 (MFDpwsDevice.dll MFWsStack.dll)包括如下命名空间:

命名空间

描述

Dpws.Device

提供一个表现DPWS设备堆栈的类,和一些控制DPWS堆栈属性的类。包含在MFDpwsDevice.dll

Dpws.Device.Services

包含一个创建和管理事件来源的类和控制主机服务终点、操作和事件的类。包含在MFDpwsDevice.dll

Ws.Services

提供管理终端服务器的操作类。包含在MFWsStack.dll

Ws.Services.Faults

包含用于处理类生成时返回错误提示的类。包含在MFWsStack.dll

Ws.Services.Mtom

包含用来处理SOAP消息中的MTOM含在MFWsStack.dll

Ws.Services.Soap

提供了一个类和一个枚举类型解析SOAP消息。包含在MFWsStack.dll

Ws.Services.Transport

包含一个提供基础网络服务的类。包含在MFWsStack.dll

Ws.Services.Utilites

提供一个用于展示调试输出,展现持续时间,验证基于UUIDs的URIs的类。包含在MFWsStack.dll

Ws.Services.WsaAddressing

包含用于处理WS- Addressing头信息的类。包含在MFWsStack.dll

Ws.Services.Xml

包含用于处理XML的类。包含在MFWsStack.dll

 

DPWS 客户端类库(MFDpwsClient.dll)包含如下命名空间

命名空间

描述

Dpws.Client

提供一个创建DPWS客户端的类

Dpws.Client.Discovery

包含一个查找和解决Request的类

Dpws.Client.Eventing

包含一个用于定制事件的类

Dpws.Client.Transport

包含一个用于发送和接收HTTP请求的类

 

3.       构建一个基于.Net Micro FrameworkDPWS应用

3.1   定义Web ServiceWSDL文件

作为DPWS中对一切服务的统一描述方式, WSDL是创建服务的必须的文件. 当然你可以选择手动创建WSDL, 不过那似乎有点麻烦 =. = ! 这里为了简便, 我就直接从桌面版的Webservice生成好了. OK.首先打开Visual Studio 2008 sp1, 创建一个asp.net webservice的项目:

 

我们就简单地定义一个叫Add的方法:

    /// <summary>

    /// 返回两个整型数的和

    /// </summary>

    [WebService(Namespace = "http://fox23.cnblogs.com/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    [System.ComponentModel.ToolboxItem(false)]

    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.

    // [System.Web.Script.Services.ScriptService]

    public class Service1 : System.Web.Services.WebService

    {

        [WebMethod]

        public int Add(int a, int b)

        {

            return a+b;

        }

}

 

Tips 事实上这里你可以不必写函数的具体实现, 事实上后面也只用到了Service1中的这个函数签名而已.

 

                   然后在浏览器里跑一下这个服务, 并访问其描述文件, 如图:

 

然后这里我将该网页另存为AddService.wsdl文件(后缀名是wsdl).

 

3.2   利用MfSvcUtil.exe创建辅助类

.Net Micro Framework 3.0 SDK中提供了一个叫MfSvcUtil的小工具, 用于从wsdl文件生成对应的DWPS辅助类, 它在$MF安装路径$"Microsoft .NET Micro Framework"v3.0"Tools目录下可以找到.

为了方便, 现在我们将之前保存的AddService.wsdl文件Copy到该目录下. 然后从命令行进入该目录, 键入命令:

MfSvcUtil AddService.wsdl 回车:

 

即开始生成以下三个辅助类:

AddService.cs - 定义了客户端请求和服务器反应的数据类型的合同类

AddServiceHostedService.cs - 从DpwsHostedService获得的主机服务

AddServiceClientProxy.cs -从DpwsClient获得的客户端代理

 

Tips 注意这里默认情况下, 生成的服务类名称为wsdl文件的名称. 你可以通过MfSvcUtil.exe”/C”参数来修改这个名称.

 

3.3   构建一个Device Host Service

上面已经把需要的辅助类生成好, 暂且不去谈那三个类的具体代码, 我们还是先看看怎么把它们用起来. 现在我们不妨来定义一个用来host这个服务的设备. 新建一个.Net Micro Framework的控制台程序. 添加对以下程序集的引用:

MFDpwsDevice.dll

MFDpwsClient.dll

MFDpwsExtentions.dll

MFWsStack.dll

然后, 将之前生成好的三个类添加到工程中来. 并添加如下引用目录:

 

using System;

using Microsoft.SPOT; 

using Dpws.Device;

using fox.cnblogs.com;//即生成类的命名空间

 

我们先给设备指定一个GUID地址:

 

Device.EndpointAddress = "urn:uuid:587066b0-440f-4652-8395-ec20cca0ec91";

 

Tips这个地址必须是urn:uuid这种GUID的格式, 不过目前MSDN上的文档已经过时了, http://msdn.microsoft.com/en-us/library/dd170121.aspx 中提到的诸如http://localhost:1234的地址格式现在是行不通的.

 

然后来配置一下这个DPWS Device, 静态类Dpws.Device.Device 用于获取和配置设备自己的一些信息. Device.ThisModel类包括配置这个服务的一些特有信息,如:服务的名字,服务的号码。Device.ThisDevice类包含一些配置设备本身的参数,如序列号等:

 

Device.ThisModel.Manufacturer = "Freesc Huang";
Device.ThisModel.ManufacturerUrl 
= "http://fox23.cnblogs.com/";
Device.ThisModel.ModelName 
= "Freesc Dpws Test Device";
Device.ThisModel.ModelNumber 
= "1.0";
Device.ThisModel.ModelUrl 
= "http://fox23.cnblogs.com/";
Device.ThisModel.PresentationUrl 
= "http://fox23.cnblogs.com/";

Device.ThisDevice.FriendlyName 
= "Service1Soap";
Device.ThisDevice.FirmwareVersion 
= "alpha";
Device.ThisDevice.SerialNumber 
= "12345678";

 

创建好一个设备, 我们还需要把服务添加到这个设备上, 首先我们需要实现之前定义的服务借口, 你在生成的AddService.cs文件中可以找到如下代码:

 

    [ServiceContract(Namespace="http://fox23.cnblogs.com/")]
    
public interface IService1Soap 
    
{       
        [OperationContract(Action
="http://fox23.cnblogs.com/Add")]
        AddResponse Add(Add req);
}

//Service1是之前定义的WebService的名称

 

现在我们再添加一个AddServiceImplementation类到工程中, 其用来实现这里的Add功能, 代码很简单, 如下:

 

    public class AddServiceImplementation : IService1Soap
    
{
        
public AddResponse Add(Add req)
        
{
            AddResponse response 
= new AddResponse();
            response.AddResult 
= req.a + req.b;
            
return response;
        }

    }

 

然后回到Main函数中:

// 添加服务
Device.HostedServices.Add(new Service1Soap(new AddServiceImplementation()));
// 开启这个DPWS设备
Device.Start();

 

OK, Host端就完成了. (不要急, 完整的代码在后面有下载;-)

 

3.4   构建一个Device Service Consumer(Client)

为了测试这个服务, 还需要做一个检测并使用这个服务的消费端. 我们再新建一个Micro Framework控制台程序, 首先要找到DPWS设备. 就像在互联网我们根据IP查找目标机器一样, 这里我们通过一个GUID来查找DPWS设备:

 

DpwsServiceDescription resolveMatch = 
Discover.DiscoveryClient.Resolve(
"urn:uuid:587066b0-440f-4652-8395-ec20cca0ec91");

这个Resolve方法通过UDP在网路上multicast并返回一些DPWS的元数据, 他们是一些ResolveMatches 的对象, 包含了服务节点的信息和服务类型信息. 然后我们需要分析设备元数据,并查找我们需要的服务:

//获得设备元数据
deviceMetadata = Discover.MexClient.Get(deviceEndpointURI);
if (deviceMetadata.Relationship.HostedServices != null)
{
//便历设备上的服务, 按指定的服务ID查找
for (int i = 0; i < deviceMetadata.Relationship.HostedServices.Count; ++i)
{
if (deviceMetadata.Relationship.HostedServices[i].ServiceID == "urn:uuid:2c7ea8f1-d812-402d-afa8-6ca9fa03a2f0")
{
ServiceEndPointURI 
= deviceMetadata.Relationship.HostedServices[i].EndpointRefs[0].Address.AbsoluteUri;
                                    }

                                }

                            }

 

然后可以测试一下服务了:

//创建一个Service的代理
Service1SoapClientProxy soapProxy = new Service1SoapClientProxy();
soapProxy.ServiceEndpoint 
= deviceMetadata.Relationship.HostedServices[0].EndpointRefs[0].Address.AbsoluteUri;
soapProxy.IgnoreRequestFromThisIP 
= false;

//调用该服务
Add mRequest = new Add();
mRequest.a 
= 2; mRequest.b = 5;//2+5
AddResponse mResponse = soapProxy.Add(mRequest);
Debug.Print(
"mResponse.MultiplyResult: " + mResponse.AddResult.ToString());

 

3.5.   RUN

现在你可以在文章末尾下载这个程序来试着运行一次, 开启两个Visual Studio, 可以各自在模拟器进行调试, 先运行Host, 再运行Client, VSoutput窗口可以看到各自的运行信息:

HOST:

urn:uuid:587066b0-440f-4652-8395-ec20cca0ec91

Device started!

CIENT:

Device endpoint found: http://192.168.1.101:8084/587066b0-440f-4652-8395-ec20cca0ec91

Found device:

 ModelName: Freesc Dpws Test Device

 ModelNumber: 1.0

 FirmwareVersion: alpha

 FriendlyName: Service1Soap

 SerialNumber: 12345678

Service endpoint found:http://192.168.1.101:8084/2c7ea8f1-d812-402d-afa8-6ca9fa03a2f0

mResponse.AddResult: 7

 

  这里要注意第一次运行时, Vista的防火墙也许会要询问你是否unblock这个应用程序, 选择unblock即可

 

4.总结

随着支持DPWS设备的不断增多, 相信这项应用会越来越多样, 越来越普及, 目前.Net Micro Framework尚未与桌面的如WCF的服务实现良好的整合, 不过.Net MF Team已经表示他们正在"work out". 那时各种设备与PC机构成的服务网络将会带来更多眩目的应用. 拭目以待吧.

参考资料:

完整代码在这里下载:DpwsSampleCode

 

Happy new year to all  ;-)

posted on 2008-12-29 12:02 Freesc Huang 阅读(2318) 评论(11) 编辑 收藏

评论

#1楼 2008-12-29 12:32 htqx[未注册用户]

在mp3用这个有意义么?

国内似乎没啥人研究。
 回复 引用   

#2楼[楼主] 2008-12-29 16:18 fox23      

@htqx
没问题,请看:
http://www.youtube.com/watch?v=vGHxWu-rWPY
 回复 引用 查看   

#3楼 2008-12-30 09:38 施炯      

Fox的文章越来越有paper的感觉了 呵呵
我实验室机子上装了一个VS2008的Team Suite版,emule上down下来的,就是装不上SP1,郁闷啊。
 回复 引用 查看   

#4楼 2008-12-30 16:52 AppleSeeker      

太强悍了....版式~~~~~~
看来好好将版式修饰下是王道~~~
 回复 引用 查看   

#5楼 2009-01-04 14:02 lbq1221119      

这个走的是http协议么?  回复 引用 查看   

#6楼[楼主] 2009-01-04 14:54 fox23      

@lbq1221119
Discovery走Udp
Event走TCP/IP
Message走http
 回复 引用 查看   

#7楼 2009-01-08 18:51 lbq1221119      

@fox23
哈 你这个我研究了一阵子,
Discovery走UDP限制了只能是内网,http也是TCP。。

Tips这个地址必须是urn:uuid这种GUID的格式, 不过目前MSDN上的文档已经过时了, 在http://msdn.microsoft.com/en-us/library/dd170121.aspx 中提到的诸如http://localhost:1234的地址格式现在是行不通的.

这个应该是2.5里面的,为了只是WS在server上面的。

你的文章是device to device的,我发现要device to server还是有点麻烦的,用到的完全不一样。。
 回复 引用 查看   

#8楼 2009-01-23 10:47 叶帆      

正好要了解DPWS,写的不错,小黄继续加油!  回复 引用 查看   

#9楼[楼主] 2009-01-29 13:03 fox23      

@叶帆
谢谢yefan大哥~
 回复 引用 查看   

#10楼 2009-10-01 08:27 djln[未注册用户]

Hi,

i cannot open the project files (.csproj) in the solution file.
 回复 引用   

#11楼 2009-10-01 08:39 djln[未注册用户]

BTW, i am using VS 2008.  回复 引用   

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

公告

These postings are provided "AS IS" with no warranties
and confer no rights.


Locations of visitors to this page

Blog Keywords
Embedded System,Visual Studio,.Net Framework,.Net Compact Framework,.Net Micro Framework,Windows Mobile,Windows Embedded CE,Emulator,WCF,CLR,Design & Pattern,C/C++,C#,Matlab,Algorithms
昵称:Freesc Huang
园龄:4年11个月
粉丝:32
关注:4

统计

  • 随笔 - 197
  • 文章 - 0
  • 评论 - 840

搜索

 

随笔分类(227)

随笔档案(197)

Blogs

Link

积分与排名

最新评论

阅读排行榜

评论排行榜

推荐排行榜