用.Net的Web服務實現天氣預報

發表于:2007-05-25來源:作者:點擊數: 標簽:web天氣預報.NET例子實現
該例子演示了利用微軟.Net框架的Web服務與天氣預報站點的硬件進行數據交換來實現Web天氣預報的服務。 微軟力推.Net的目的,用他自己的話來說就是“使人們能夠在任何時候、任何地點以及任何設備上通過我們 開發 的軟件發揮最大的潛能”。在這里大多數人可能認
該例子演示了利用微軟.Net框架的Web服務與天氣預報站點的硬件進行數據交換來實現Web天氣預報的服務。

  微軟力推.Net的目的,用他自己的話來說就是“使人們能夠在任何時候、任何地點以及任何設備上通過我們開發的軟件發揮最大的潛能”。在這里大多數人可能認為微軟所講的“任何設備”是指袖珍PC、手持設備、臺式電腦及筆記本電腦等。下面的例子我們將向大家展示.Net如何使那些電腦硬件設備驅動程序開發人員發揮自己的潛能,這些設備驅動程序可能和一些專用的PC控制器或PC的標準端口直接通訊。這些驅動程序開發人員大多依靠Windows的驅動開發工具包(DDK)及其其他各種工具,如可安裝文件系統開發工具包(IFS)等。雖然這些微軟的工具包并沒有隨著.Net的推出而改變,但是.Net構架仍然給這些硬件設備開發帶來了新的機遇。
 
  我們將要構造的示例方案的目的就是通過專用的PC卡自動采集來自于不同天氣情報采集點的天氣信息。PC卡可以通過每個采集點的標識ID來同時控制每個采集點的數據,按要求每個采集點可以提供該點的溫度、濕度和氣壓等數據。
 
  我們的目標是讓用戶通過互聯網(Web)獲得指定采集點的天氣預報信息。接下來我們開始結構設計。首先需要為PC卡寫一個Windows的驅動程序以便PC卡可以讀取指定采集點的天氣信息,另外我們還需要利用.Net構造一個網絡服務(Web Service)以便互聯網用戶可以通過Internet訪問采集到的天氣信息數據。

  .Net的托管代碼是不能直接訪問Windows的內核的。所有我們必須先利用非托管代碼寫一個用戶級(User level)的模塊以便網絡服務和PC卡的驅動程序之間可以相互交流數據。

  PC卡的驅動程序接口

  假設我們PC采集卡已安裝到專用PC上,而且采集點到PC采集開的信號電纜也連接好。接下來的任務就是驅動程序開發人員開始開發硬件驅動程序。

  我們并不打算深入研究如何開發PC卡的硬件驅動程序。其實網上有很多介紹開發驅動程序的工具和資源,也有一些介紹在NT和XP下開發驅動程序差異的文章。我們的主要目的是關心采集數據的封裝形式以及用戶模塊和驅動程序通訊的方法。

  我們準備有下面定義的結構來封裝采集到的數據:

  typedef struct {

  unsigned long stationID;

  unsigned long state; // for management purposes

  unsigned long timeStamp;

  double temperature; // celcius

  double humidity; // percent
  
  double airPressure; // millibar

  } WEATHER_DATA, *PWEATHER_DATA;

 從PC卡讀取數據我們可以利用Win32 API - DeviceIOControl(...)。為了調用該函數設備驅動程序和用戶程序必須共享用戶定義的IOCTL碼。為了簡單起見,我們用WEATHER_DATA結構表示用戶程序和驅動程序共享的數據緩沖區。但是在實際應用中,應該小心謹慎,您可以參考微軟的技術文章Q126416和Q186775。

  用戶要求得到指定的采集點的天氣信息的過程如下:

  1.用戶程序分配WEATHER_DATA結構,設置 stationID 和 dataTag。

  2.用戶程序利用Win32 API - CreateFile(...)打開與PC卡相關聯的設備句柄。

  3.用戶程序調用DeviceIOControl(),并將結構 WEATHER_DATA 作為參數。

  4.驅動程序處理調用,利用用戶選擇的數據采集點的數據填充WEATHER_DATA數據緩沖區。(在我們的例子中,用虛擬數據以模仿顯示中的數據采集。)

  5.驅動程序返回數據個用戶程序,結束DeviceIOControl()調用。
  
  6.用戶程序處理得到的數據。


  以下的頭定義文件為驅動程序和用戶程序共用:

  // weather_common.h

  // Common definitions used by both user level module and

  // kernel driver

  //

  #define WEATHER_TYPE 40000

  // The IOCTL function codes from 0x800 to 0xFFF

  // are for customer use.

  #define IOCTL_GET_WEATHER_DATA

  CTL_CODE( WEATHER_TYPE, 0x900, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

  // Define common used weather data structure

  typedef struct {

  unsigned long stationID;

  unsigned long state;

  unsigned long timeStamp;

  double temperature;

  double humidity;
 
  double airPressure;

  } WEATHER_DATA, *PWEATHER_DATA;


  接下來的代碼是用戶端的實現:

  // UserLevelModule.cpp

  //

  // Implementation of user level module

  ...
  
  DWORD dwBytesReturned;

  // Create structure and fill initial data

  WEATHER_DATA dataStruct;

  // specify station to request

  dataStruct.stationID = stationID;

  ...

  // Open driver

  HANDLE hDriver;

  hDriver = CreateFile(“\\.\Device\WeatherDevice”,...);

  ...
  
  // Issue control call to driver passing prepared structure

  DeviceIOControl(hDriver,IOCTL_WEATHER_DATA,

  (void*)&dataStruct,sizeof(dataStruct),

  (void*)&dataStruct,sizeof(dataStruct),

  &dwBytesReturned,NULL);

  // If suclearcase/" target="_blank" >cceeded the structure now contains

  // the requested data in data

  ...

  // Close driver

  CloseHandle(hDriver);

接下來是驅動程序的部分代碼:

  // WeatherDrv.c

  //

  // Implementation of kernel driver

  NTSTATUS

  WeatherDispatch(

  IN PDEVICE_OBJECT DeviceObject,

  IN PIRP Irp
  
  )

  {

  ...

  pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

  // Dispatch based on major fcn code.

  switch (pIrpStack->MajorFunction)
  
  {

  ...

  case IRP_MJ_DEVICE_CONTROL:

  // Dispatch on IOCTL

  switch (pIrpStack->Parameters.DeviceIoControl

  .IoControlCode)

  {

   case IOCTL_GET_WEATHER_DATA:

   pWeatherData = (PWEATHER_DATA)

   pIrp->AssociatedIrp.SystemBuffer;

  if(pWeatherData != NULL)

  {

  // Fill time stamp in data structure

  KeQuerySystemTime(&sysTime);

  RtlTimeToTimeFields(&sysTime,&tFields);

  pWeatherData->timeStamp = tFields.Second

  + 100 * tFields.Minute

  + 10000 * tFields.Hour;

  // Emulate controller card work with

  // sample data

  pWeatherData->temperature = 25;

  pWeatherData->humidity = 60;

  pWeatherData->airPressure = 1015;

  }

  pIrp->IoStatus.Information =
  
  sizeof(WEATHER_DATA);

  break;

  default:

  break;

  }
 
  Status = STATUS_SUCCESS;

  break;

  ...
  
  // Complete request

  }

 
用戶端代碼

  驅動程序以及驅動程序和用戶程序的通訊協議定義好了以后,接下來就是開發用戶端模塊了。

  我們可以開發一個應用程序或者動態連接庫。在這里我們實現一個動態連接庫。以下代碼演示了如何輸出一個函數供外部調用:

  // weatherDrvCtrl.h

  //

  // Declaration of GetWeatherData()

  DWORD WINAPI GetWeatherData(WEATHER_DATA* pData);

  // weatherDrvCtrl.cpp

  //

  // Definition of GetWeatherData()

  DWORD WINAPI GetWeatherData(

  WEATHER_DATA* pData)

  {

  HANDLE hDriver;

  DWORD dwErr = ERROR_SUCCESS;

  DWORD dwBytesReturned;

  // Open driver

  HANDLE hDriver;

  hDriver = CreateFile(DRIVER_DEVICE_NAME,...);

  if(hDriver != INVALID_HANDLE_VALUE)

  {

  // Issue control call to driver

  // passing prepared structure

  dwErr = DeviceIOControl(hDriver,IOCTL_WEATHER_DATA,

  (void*)&dataStruct,sizeof(dataStruct),

  (void*)&dataStruct,sizeof(dataStruct),

  &dwBytesReturned,NULL);

  if(!dwErr)

  {

  // If succeeded the structure now contains
  
  // requested data in data field

  }

  // Close driver

  CloseHandle(hDriver);

  }

  else

  {

  // Handle device open error;

  }

  return dwErr;

  }
附件的weatherDrvCtrl項目是用Visual Studio .Net構造的,我們還提供了一個Win32的應用程序以供你測試應用程序(weatherDrvCtrl)和驅動程序(weatherDrv)。

  到現在為止我們已經完成了驅動程序和用戶端調用的所有工作。任何用戶程序都可以通過調用動態庫輸出函數得到指定采集點的天氣信息數據。

  網絡服務Web Service

  下面我們來實現.Net的網絡服務,以便互聯網用戶可以享受我們的服務。利用Visual Studio .Net創建Web Service很簡單:

  1.啟動Visuao Studio .Net;

  2.新健一個新項目,選擇 C# ASP .Net Web服務。

  3.編寫數據結構:

[ StructLayout( LayoutKind.Sequential )]

public struct WeatherData

{

public UInt32 stationID;

public UInt32 state;

public UInt32 timeStamp;

public Double temperature;

public Double humidity;

public Double airPressure;

}


4.利用屬性DllImport綁定動態庫:weatherDrvCtrl.DLL。

[DllImport("weatherDrvCtrl.dll")]

static extern unsafe uint GetWeatherData

(ref WeatherData data);


5.創建一個Web方法:

[WebMethod(Description=”Get weather data and station state from specified weather station”)]

public unsafe WeatherData

QueryWeatherData(uint stationID)

{

// Create and initialize data structure

WeatherData weatherData = new WeatherData();

weatherData.stationID = stationID;

// Call user level wrapper for device driver

uint dwRet = GetWeatherData(ref weatherData);

// If call failed, hqndle error here...

return weatherData;

}

  6.生成并測試。

  如果您按照上述過程正確操作,應該得到結果。這是一個重要的里程碑。因為你已經創建了一個完整的Web服務,您可以注冊您的服務讓更多的人使用它。(具體的注冊Web服務請參考www.uddi.org)(代碼實驗室)

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97