当前位置: 首页 > news >正文

在.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 
ExpandedBlockStart.gifContractedBlock.gif    
{       
        [OperationContract(Action
="http://fox23.cnblogs.com/Add")]
        AddResponse Add(Add req);
}

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

 

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

 

     public   class  AddServiceImplementation : IService1Soap
ExpandedBlockStart.gifContractedBlock.gif    
{
        
public AddResponse Add(Add req)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            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 )
ExpandedBlockStart.gifContractedBlock.gif
{
//便历设备上的服务, 按指定的服务ID查找
for (int i = 0; i < deviceMetadata.Relationship.HostedServices.Count; ++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if (deviceMetadata.Relationship.HostedServices[i].ServiceID == "urn:uuid:2c7ea8f1-d812-402d-afa8-6ca9fa03a2f0")
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
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机构成的服务网络将会带来更多眩目的应用. 拭目以待吧.

参考资料:

  • The Devices Profile for Web Service specification 
  • whitepaper on DPWS, WS-Discovery, and SOAP-over-UDP
  • http://www.microframework.nl/2008/12/10/dpws-my-first-try-with-a-little-succes/
  • A Technical Introduction to the Devices Profile for Web Services, Jeffrey Schlimmer,May 2004
  • <.Net Micro Framework嵌入式开发入门与典型实例>,国内第一本介绍.Net MF的书

完整代码在这里下载:DpwsSampleCode

 

Happy new year to all  ;-)

相关文章:

  • PIC16F877A 内部EEPROM读写实验利用内部函数
  • 如何让DevExpress的DateEdit控件正确显示日期的周名
  • 手把手教你配置Windows2003集群
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • MSDN中文Webcast for Windows Phone
  • C++ 预编译头文件
  • C#学习笔记(七)——定义类
  • C#学习笔记(五)——函数
  • Google CEO 定义 Web 3.0
  • 判断字符串是否是回文字符串或者是否含有回文字符子串 (我是从两颗番茄的博客看的题目,然后自己编的) 不断学习!!...
  • DICOMDIR结构
  • MVC2 Area实现网站多级目录
  • IBM Java多线程 - 4.共享对数据的访问
  • TADOQuery池
  • Windows7问题集
  • 【译】JS基础算法脚本:字符串结尾
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • CSS盒模型深入
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • magento 货币换算
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Promise面试题2实现异步串行执行
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Vue官网教程学习过程中值得记录的一些事情
  • 安装python包到指定虚拟环境
  • 大型网站性能监测、分析与优化常见问题QA
  • 第2章 网络文档
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 聚类分析——Kmeans
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 前端学习笔记之观察者模式
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 一些css基础学习笔记
  • 原生 js 实现移动端 Touch 滑动反弹
  • 移动端高清、多屏适配方案
  • 昨天1024程序员节,我故意写了个死循环~
  • ​520就是要宠粉,你的心头书我买单
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​Python 3 新特性:类型注解
  • $.ajax()
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (原創) 物件導向與老子思想 (OO)
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .NET MVC 验证码
  • .net MVC中使用angularJs刷新页面数据列表
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .NET的数据绑定