DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 使用 XML-RPC 為 C++ 應用程序啟用 Web 服務
使用 XML-RPC 為 C++ 應用程序啟用 Web 服務
編輯:XML詳解     

引言

  Internet 現在的受歡迎程度越來越高,由於這個原因及其固有的優勢,促使開發人員和 IT 部門開始著手將復雜的 C/C++ 業務和科學應用程序向基於 Web 的環境遷移。簡單對象訪問協議(Simple Object Access Protocol,SOAP)、代表性狀態傳輸(Representational State Transfer,REST)以及 XML 遠程過程調用協議(XML Remote Procedure Call,XML-RPC)等 Web 服務協議可幫助將此類遺留應用程序集成到萬維網,例如,可以使用 XML-RPC 作為將現有 C/C++ 程序與其他客戶端技術集成的機制。這篇文章將幫助您確定何時選擇 XML-RPC 而不使用 SOAP 與 REST。另外,本文還提供了詳細步驟指南以及使用開放源代碼 XML-RPC 庫的 C++ 集成示例代碼片段。

  為什麼選擇 XML-RPC?

  集成 C/C++ 的挑戰可以通過多種方式加以解決。C/C++ 代碼集成的典型方法包括通過公共對象請求代理體系結構(Common Object Request Broker Architecture,CORBA)、分布式組件對象模型(Distributed Component Object Model,DCOM)、遠程方法調用(Remote Method Invocation,RMI)Internet ORB互聯協議(Internet Inter-ORB Protocol,IIOP)以及 Java™ 本機接口(Java™ Native Interface,JNI)等進行集成。

  圖 1 顯示了利用現有 C++ 代碼集成(使用上面提到的典型方法)的采用不同編程語言(Java、VC++、PL/1)開發的三個不同應用程序。

  圖 1. 沒有 XML-RPC 的當前方案

使用 XML-RPC 為 C++ 應用程序啟用 Web 服務

  正如您看到的,C++ 代碼應為每個 RMI/IIOP/JNI、CORBA 和 DCOM 客戶端集成技術公開相應的接口。這就要求進行三次開發工作,顯然會使部署和管理此類復雜接口的過程變得更為困難和麻煩。

  在這些情況下,XML-RPC 是一個更好的選擇,因為它可能幫助簡化開發、部署和管理工作。

  圖 2. 使用 XML-RPC

使用 XML-RPC 為 C++ 應用程序啟用 Web 服務

  圖 2 顯示了如何使用 XML over HTTP 通過遠程過程調用來調用 C++ 程序。SOAP 和 REST 等備選技術也能用於相同的目的。不過,您將在下一部分中了解到,這些技術之間存在一些關鍵區別。

  SOAP、XML-RPC 及 REST 間的對比

  盡管這三個協議都支持 XML-RPC over HTTP,但就 C++ 而言,它們彼此之間是有區別的。表 1 提供了這些協議的各個元素間詳細的比較。

  表 1. SOAP、XML-RPC 及 REST 間的對比

SOAP XML-RPC REST 定義 SOAP 是用於在分散的分布式環境中進行信息交換的輕量級協議。該協議基於 XML,包括三個部分:信封、一組編碼規則以及用於表示遠程過程調用和響應的約定。 這是使用 HTTP 作為傳輸協議和使用 XML 作為編碼方式的遠程過程調用。XML-RPC 的設計力求簡單,並同時允許傳輸、處理和返回復雜數據結構。 代表性狀態傳輸旨在反映設計良好的 Web 應用程序的行為圖像:由網頁組成的網絡,其中用戶通過選擇鏈接繼續進行使用,選擇鏈接將導致將下一頁傳輸給用戶並進行呈現,以供其使用。 目標 SOAP 可實現用戶定義的數據類型,提供指定接收者的功能、消息特定的處理控制以及其他功能,從而對 XML-RPC 進行了擴展。 非常簡單且條理清楚的可擴展格式。Html 編碼人員應該能夠查看包含 XML-RPC 過程調用的文件,理解其進行的工作,並能夠對其進行修改,只需一兩次嘗試就能使其正常工作。此協議非常容易實現,可以快速對其進行調整,以在其他環境或其他操作系統上運行。 創建 REST 的目的是為了提供有關 Web 應該如何運行的設計模式,並作為 Web 標准和設計 Web 服務的指導框架。 支持的數據類型 整數、Boolean、ASCII 字符串、雙精度帶符號浮點數、日期時間、結構、數組、字節數組、枚舉、用戶定義數據類型、多態訪問器 整數、Boolean、ASCII 字符串、雙精度帶符號浮點數、日期時間、結構、數組。 特定於實現。通常支持的類型有整數、Boolean、ASCII 字符串、雙精度帶符號浮點數、日期時間、集合、列表、屬性。 簡單性 比 XML-RPC 略微復雜 易於理解和進行開發 特定於實現 穩定性 W3C 接受的標准 不是標准 體系結構參考。不需要標准 互操作性 無法與 REST/XML-RPC 互操作 無法與 REST/SOAP 互操作 無法與 SOAP/XML-RPC 互操作 工具 很多主要公司(包括 IBM 和 Microsoft)均已開始在其工具中支持 SOAP。 工具仍在開發中。 並沒有很多工具支持。 自定義能力 高度可自定義,不受數據類型和協議限制 輕量級,只能在 HTTP 上工作,具有有限的數據類型支持 只能在 HTTP 上工作 庫 有很多開放源代碼庫可用。 有很多開放源代碼庫可用。將在下面的部分進行說明 並沒有很多實現庫可用

  表 2. C++ 的各種 XML-RPC 實現

庫和包名稱 說明 PDEL Packet Design Embedded Library 是一個 C 庫,其中通過 http_xml_send_xmlrpc 和 http_servlet_xmlrpc 方法包含了客戶機和服務器的 XML-RPC 實現。這些函數將幫助通過 HTTP 傳輸協議發送自定義 XML 數據。這個包還包含很多 XML-RPC 之外的其他功能。 XMLRPC++ 這是 XML-RPC 的 C++ 實現。其中提供了簡單的服務器和客戶機。通過使用面向對象的技術,我們可以集成這些服務器和客戶機類,並實現我們自己的 XML-RPC 服務器,以將業務功能作為服務公開。在本文中,我們的示例實現及相關示例將使用這個庫。 XMLRPC-C 這是一個 C 實現,可供 C 和 C++ 應用程序用於將這些方法作為服務公開。此包中包括一個 abyss Web 服務器。為了公開 C++ 方法,我們可以為所需的 C++ 方法編寫 C 樣式的包裝,然後使用此庫公開此方法。

  安裝 XML-RPC++ 庫

  為 C++ 程序啟用 XML-RPC 的第一步是下載並安裝 XML-RPC 庫實現。為 C++ 程序提供了各種實現。可以在參考資料部分獲得一個指向更多實現的鏈接。

  我們的示例程序將使用 XMPLRPC++ 實現。有關將此實現下載並安裝到 Linux、AIX、32 位 Windows 平台以及其他類似平台的詳細信息,請參閱參考資料部分。我們的示例實現將基於 Red Hat 9 平台,使用的是 XML-RPC++ 0.7 庫。

  示例 C++ 應用程序

  此處的示例應用程序是一個簡單的兩個整數相加的操作,將使用名為“operations”的用戶定義類。清單 1 顯示了 Operations 類的代碼片段。

  清單 1. Operations

class Operations {
public:
  int add();
  Operations(int i, int j);
private:
  int op1;//Operand 1
  int op2;//Operand 2
};

  該類的構造函數接受兩個整數參數,並將其分別設置為私有變量 op1 和 op2。該類的 add 方法如清單 2 中所示。這個方法就是要作為 XML-RPC 服務公開的方法。

  清單 2. Operations.cpp

int Operations::add()
{
    std::cout << "Sum of "<<op1<<" + "<<op2<<" = "<<op1+op2<<std::endl;
    return(op1 + op2);
}

  XML-RPC 庫的組件

  在此部分,我們將使用一個類關系圖來說明 XML-RPC 庫的各個組件,並介紹其如何與我們服務器端的 Operations 類通過接口連接。

  圖 3. XML-RPC 庫和示例應用程序的類關系圖

使用 XML-RPC 為 C++ 應用程序啟用 Web 服務

  表 3 對每個類進行了詳細說明。

  表 3. 類詳細信息

類名稱 用途 Operations 要公開的 add 方法在該類中實現 Add 調用 Operations 的 add 方法的包裝類。該類也從 myXMLRpcServerMethod 繼承 myXMLRpcServerMethod 該類從 XML-RPC 庫的 XMLRpcServerMethod 類繼承。該類的 execute 將在 Add 類中通過繼承覆蓋。 XMLRpcServermethod 需要向服務器注冊的每個方法都必須通過 myXmlRpcServerMethod 類從該類進行繼承,並實現自己的 execute 方法。這個 execute 方法將為公開的實際服務的包裝。服務器收到 XML-RPC 調用時,將會直接觸發此包裝類的 execute 方法。在我們的示例中,Add 將為包裝類,從客戶端調用“Add”服務時,將調用其 execute 方法。 myXMLRpcServer 該類具有兩個重要的私有變量

  pm_serverMethods:指向在服務器中注冊的 myXMLRpcServerMethods 的指針列表。

  pm_XMLRpcServer:用於設置服務器 IP、端口和其他屬性。

  三個重要的方法

  Class constructor:使用 IP/端口詳細信息初始化服務器對象,並將其綁定。

  pm_registerMethods:創建指向 Add 類的指針對象,並將其加入列表 pm_serverMethods 中。

  run:XMLRpcServer 類中 work 方法的包裝

XMLRpcServer 該類是創建服務器對象的 XML-RPC 服務器類。該類具有以下兩個重要的方法

  bindAndListen(port):綁定並偵聽指定的特定端口

  work(...):啟動服務器

  清單 3 顯示了上表中每個類的每個 .cpp 文件的代碼。由於 xmlRpcServer 和 xmlRpcServerMethod 是在 XML-RPC 庫中實現的,因此我們將重點討論剩下的四個類。

  清單 3. myXMLRpcServer.cpp

#include "myXMLRpcServer.h"
using namespace XMLRpc;
using namespace std;
myXmlRpcServer::myXMLRpcServer()
{
//call register methods
pm_registerMethods();
//set port bind and listen
int port = 8085;
pm_XMLRpcServer.bindAndListen(port);
std::cout<<"XMLRpcSever running in port "<<port<<std::endl;
}
void
myXMLRpcServer::pm_registerMethods()
{
    Add* a=new Add(&pm_XMLRpcServer);
    myXMLRpcServerMethod *p=a;
    pm_serverMethods.push_back(p);
}
void
myXMLRpcServer::run()
{
    pm_XMLRpcServer.work(-1);
}

  清單 4. myXMLRpcServer.h

#include <iOStream>
#include "myXMLRpcServerMethods.h"
#include "XMLRpc.h"
class myXMLRpcServer {
public:
    myXMLRpcServer();
    void run();
private:
    void pm_registerMethods();
    XmlRpc::XmlRpcServer pm_XMLRpcServer;
    std::list< myXMLRpcServerMethod* > pm_serverMethods;
};

  清單 5 和清單 6 顯示了用於將方法注冊到 XmlRpc Server(作為 XML-RPC 庫的一部分提供)的類的代碼。

  清單 5. myXMLRpcServerMethods.cpp

#include <iOStream>
#include "myXMLRpcServer.h"
#include "Operations.h"
using namespace std;
Add::Add(XmlRpcServer* s) : myXMLRpcServerMethod("Add", s) {};
Void Add::execute(XmlRpcValue & params, XMLRpcValue& result)
{
Operations a(10,12);
try
  {
   cout << "Inside Add::execute methodn";
   result = a.add();
  }
 catch(std::exception & stde)
  {
   throw XMLRpcException(stde.what());
  }
}

  清單 6. myXMLRpcServerMethods.h

class myXmlRpcServerMethod : public XMLRpcServerMethod
{
public:
 myXMLRpcServerMethod
  (const char *name, XmlRpcServer * server):XMLRpcServerMethod(name, server) {}
  virtual void execute(XmlRpcValue & params, XMLRpcValue& result) {assert(0);}
};
class Add:public myXMLRpcServerMethod
{
public:
  Add(XMLRpcServer* s);
  virtual void execute(XmlRpcValue & params, XMLRpcValue& result);
};

  服務器驅動程序

  服務器端的入口點將是服務器驅動程序。將從此處實例化 myXMLRpcServer 對象,並調用 run() 方法,而後者將最終啟動服務器。

  清單 7. myServerDriver.cpp

#include <iOStream>
#include "myXMLRpcServer.h"
int main(int argc, char* argv[])
{
    myXMLRpcServer GeeBoomBaa;
    std::cout<<"About to run the servern";
    GeeBoomBaa.run();
    return 0;
}

  啟動服務器

  為了編譯該代碼,請記住包含 (XML_RPC_INSTALL_DIR)/src 和 (XML_RPC_INSTALL_DIR)/include 目錄。為了進行鏈接,請包含 libXmlRpc.a 庫。代碼成功編譯並鏈接後,將獲得一個可執行文件,該文件就是 XML-RPC 服務器。在我們的示例實現中,服務器將運行於 localhost 上,並偵聽端口 8085。這個設置硬編碼在 myXMLRpcServer.cpp 文件中。也可以使程序讀取配置文件,或者從命令行提示符將此作為參數傳遞給程序。運行成功進行了編譯和鏈接後得到的 a.out 程序,以啟動服務器。

  示例客戶機

  示例客戶機應該從 XML-RPC 庫提供的 XMLRpcClIEnt 類實例化一個對象。該類的“execute(...)”將實際接受三個參數:

  方法名稱,const char* 類型

  端口號,const int 類型

  可選的 URL 字符串,以作為 http get header 中的 URI 進行發送

  清單 8 顯示了一個示例客戶機,此客戶機將執行“add(...)”方法,並在客戶端輸出結果。

  清單 8. sampleClIEnt.cpp

#include <iOStream>
#include "XMLRpc.h"
using namespace XMLRpc;
int main(int argc, char* argv[])
{
    const char *server = "localhost";
    const int port = 8085;
    const char *uri = NULL;
    XMLRpcValue args, res;
    XMLRpcClIEnt c( server, port, uri);
    c.execute("Add", args, res);
    std::cout<<"result is "<<res<<std::endl;
}

  結束語

  XML-RPC 是一個簡單而強大的輕量級消息傳遞協議,可支持基於 XML 的跨異類平台通信。此標准固有的簡單性在將遺留應用程序與企業集成方面表現得非常強大而實用。由於各個 XML-RPC 實現都是開放源代碼的,使得此技術在企業應用程序集成領域越來越受歡迎。隨著越來越多的成熟 XML-RPC 工具的出現,我們可以預見,在不久的將來,此技術將成為企業內部集成的“事實”標准。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved