在.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

然後, 將之前生成好的三個類添加到工程中來. 並添加如下引用目錄:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> using System;

using Microsoft.SPOT;

using Dpws.Device;

using fox.cnblogs.com; // 即生成類的命名空間

我們先給設備指定一個GUID地址:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 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類包含一些配置設備本身的參數,如***等:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> Device.ThisModel.Manufacturer = " FreescHuang " ;
Device.ThisModel.ManufacturerUrl
= " http://fox23.cnblogs.com/ " ;
Device.ThisModel.ModelName
= " FreescDpwsTestDevice " ;
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文件中可以找到如下代碼:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> [ServiceContract(Namespace = " http://fox23.cnblogs.com/ " )]
public interface IService1Soap
ExpandedBlockStart.gifContractedBlock.gif
{
[OperationContract(Action
="http://fox23.cnblogs.com/Add")]
AddResponseAdd(Addreq);
}

// Service1是之前定義的WebService的名稱

現在我們再添加一個AddServiceImplementation類到工程中, 其用來實現這裏的Add功能, 代碼很簡單, 如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public class AddServiceImplementation:IService1Soap
ExpandedBlockStart.gifContractedBlock.gif
{
publicAddResponseAdd(Addreq)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
AddResponseresponse
=newAddResponse();
response.AddResult
=req.a+req.b;
returnresponse;
}

}

然後回到Main函數中:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> // 添加服務
Device.HostedServices.Add( new Service1Soap( new AddServiceImplementation()));
// 開啓這個DPWS設備
Device.Start();

OK, Host端就完成了. (不要急, 完整的代碼在後面有下載;-)

3.4 構建一個Device Service Consumer(Client)

爲了測試這個服務, 還需要做一個檢測並使用這個服務的消費端. 我們再新建一個Micro Framework控制檯程序, 首先要找到DPWS設備. 就像在互聯網我們根據IP查找目標機器一樣, 這裏我們通過一個GUID來查找DPWS設備:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> DpwsServiceDescriptionresolveMatch =
Discover.DiscoveryClient.Resolve(
" urn:uuid:587066b0-440f-4652-8395-ec20cca0ec91 " );

這個Resolve方法通過UDP在網路上multicast並返回一些DPWS的元數據, 他們是一些ResolveMatches 的對象, 包含了服務節點的信息和服務類型信息. 然後我們需要分析設備元數據,並查找我們需要的服務:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> // 獲得設備元數據
deviceMetadata = Discover.MexClient.Get(deviceEndpointURI);
if (deviceMetadata.Relationship.HostedServices != null )
ExpandedBlockStart.gifContractedBlock.gif
{
//便歷設備上的服務,按指定的服務ID查找
for(inti=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;
}

}

}

然後可以測試一下服務了:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> // 創建一個Service的代理
Service1SoapClientProxysoapProxy = new Service1SoapClientProxy();
soapProxy.ServiceEndpoint
= deviceMetadata.Relationship.HostedServices[ 0 ].EndpointRefs[ 0 ].Address.AbsoluteUri;
soapProxy.IgnoreRequestFromThisIP
= false ;

// 調用該服務
AddmRequest = new Add();
mRequest.a
= 2 ;mRequest.b = 5 ; // 2+5
AddResponsemResponse = 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 ;-)