XML-RPC 和 XML-RPC 服務(wù)器類
CodeIgniter 的 XML-RPC? 類允許你發(fā)送請求到另一個服務(wù)器, 或者建立一個你自己的XML-RPC服務(wù)器來接受請求.
什么是XML-RPC?
這是一個非常簡單的兩臺計算機使用XML通過互聯(lián)網(wǎng)進行通信的方法. 一臺計算機 , 我們稱之為 客戶端 , 發(fā)送一個XML-RPC 請求 給另外一臺計算機 , 我們稱之為 服務(wù)器. 當服務(wù)器收到請求并加以處理,然后將 結(jié)果 返回給客戶端.
例如,使用 MetaWeblog 的 API(應(yīng)用程序接口) , 一個XML-RPC客戶端(通常是桌面發(fā)布工具)會發(fā)送一個請求到運行在你網(wǎng)站的XML-RPC服務(wù)端. 這個請求有可能是要發(fā)布一篇新的網(wǎng)志,或者是要修改已存在的網(wǎng)志. 當XML-RPC服務(wù)器接收到請求,將檢驗請求并且決定調(diào)用何種類/方法來處理請求.一旦處理完畢,服務(wù)器將返回一個響應(yīng)信息.
如果要查看更詳細的規(guī)范,你可以瀏覽 XML-RPC 網(wǎng)站.
初始化類
像CodeIgniter的大多數(shù)類一樣, XML-RPC 和 XML-RPCS 類 在你的控制器中調(diào)用 $this->load->library 方法來進行初始化:
使用以下代碼載入XML-RPC類庫:
$this->load->library('xmlrpc');
一旦XML-RPC類被載入, XML-RPC 庫的對象就可以使用了: $this->xmlrpc
使用下面的方法載入 XML-RPC 服務(wù)器類:
$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');
一旦加入,可以通過 $this->xmlrpcs 使用 xml-rpcs 庫對象: $this->xmlrpcs
注意:? 使用 XML-RPC 服務(wù)器,必須同時載入 XML-RPC 類和 XML-RPC 服務(wù)器類。
發(fā)送 XML-RPC 請求
發(fā)送一個請求到 XML-RPC 服務(wù)器,需指定如下信息:
- 服務(wù)器的 URL
- 你要調(diào)用的服務(wù)器上的方法。
- The 請求 數(shù)據(jù) (說明見下面).
下面是一個簡單的例子,它發(fā)送一個簡單的 Weblogs.com ping 到Ping-o-Matic
$this->load->library('xmlrpc');
$this->xmlrpc->server('http://rpc.pingomatic.com/', 80);
$this->xmlrpc->method('weblogUpdates.ping');
$request = array('My Photoblog', 'http://www.my-site.com/photoblog/');
$this->xmlrpc->request($request);
if ( ! $this->xmlrpc->send_request())
{
????echo $this->xmlrpc->display_error();
}
說明
以上代碼初始化XML-RPC類,設(shè)置了服務(wù)器的URL和要調(diào)用的方法(weblogUpdates.ping). 請求(在此例中為你網(wǎng)站的標題和URL)被放在一個數(shù)組中使用 request() 函數(shù)傳輸、編譯。最后,整個請求發(fā)出,如果send_request()方法返回 false,我們將顯示XML-RPC 服務(wù)器發(fā)回的錯誤信息。
請求剖析
一個 XML-RPC 請求只是你發(fā)送到 XML-RPC 服務(wù)器的數(shù)據(jù)。請求中的每個數(shù)據(jù)片斷也被稱為請求參數(shù)。在上面的示例中,有兩個參數(shù):你網(wǎng)站的URL和標題。當 XML-RPC 服務(wù)器接到你的請求,服務(wù)器會尋找請求參數(shù)。
請求參數(shù)必須放在數(shù)組中傳輸,每個參數(shù)可以是七種數(shù)據(jù)類型中的任一種(字符串,數(shù)字,日期,等等)。如果你的參數(shù)是字符串外的其它類型,則必須在請求數(shù)組中包含數(shù)據(jù)類型。
下面是一個包含三個參數(shù)的簡單數(shù)組示例:
$request = array('John', 'Doe', 'www.some-site.com');
$this->xmlrpc->request($request);
如果你使用除字符串以外的其它類型,或有幾種不同的數(shù)據(jù)類型,你需要將每個參數(shù)單獨放到一個數(shù)組中,并在數(shù)組第二個位置給出數(shù)據(jù)類型。
$request = array (
???????????????????array('John', 'string'),
???????????????????array('Doe', 'string'),
???????????????????array(FALSE, 'boolean'),
???????????????????array(12345, 'int')
?????????????????);
$this->xmlrpc->request($request);
數(shù)據(jù)類型 中包括完成的數(shù)據(jù)類型列表。
創(chuàng)建 XML-RPC 服務(wù)器
XML-RPC 服務(wù)扮演著交通警察的角色,等待進入的請求,并將它們轉(zhuǎn)到恰當?shù)暮瘮?shù)進行處理。
要創(chuàng)建自己的 XML-RPC 服務(wù)器,包括在接受請求的控制器中初始化 XML-RPC 服務(wù)器類,然后設(shè)置一個指向映射數(shù)組以便收到的請求可以被發(fā)送到恰當?shù)念惻c方法來處理。
下面用一個例子來說明:
$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');
$config['functions']['new_post'] = array('function' => 'My_blog.new_entry'),
$config['functions']['update_post'] = array('function' => 'My_blog.update_entry');
$config['object'] = $this;
$this->xmlrpcs->initialize($config);
$this->xmlrpcs->serve();
上面的例子中有一個包含兩個服務(wù)器允許的特定請求方法的數(shù)組。這些被允許的方法在數(shù)組的左邊,當收到其中任何一個方法時,它會被立刻映射到數(shù)組右邊所列出的類與方法。
'Object'是一個特殊的鍵,它是你傳遞的類的實例,這個鍵是必要的,尤其是當你映射到的方法不是 Codeigniter 超類的一部分。
換句話說,如果 XML-RPC 客戶端發(fā)送一個請求到 new_post 方法,你的服務(wù)器會加載 My_blog 類并調(diào)用 new_entry 函數(shù)。如果這個請求是到 update_post 方法的,那么你的服務(wù)器會加載 My_blog 類并調(diào)用 update_entry 函數(shù)。
上面例子中的函數(shù)名是任意的。你可以決定這些函數(shù)在你的服務(wù)器上叫什么名字,如果你使用的是標準的 API,比如:Blogger 或者 MetaWeblog 的 API,你必須使用標準的函數(shù)名。
這里還有兩個附加的配置項,可以在服務(wù)器類初始化時配置使用。debug 設(shè)為 TRUE 以便調(diào)試,xss_clean 可被設(shè)置為 FALSE 以避免數(shù)據(jù)被安全類庫的 xss_clean 函數(shù)過濾。
處理服務(wù)器請求
當 XML-RPC 服務(wù)器收到請求并加載類與方法來處理時,服務(wù)器會傳遞一個包含客戶端發(fā)送數(shù)據(jù)的對象到指定的方法。
在上面的例子中,如果請求的是 new_post 方法,服務(wù)器請求的類與方法會像這樣:
class My_blog extends CI_Controller {
????function new_post($request)
????{
????}
}
$request 變量是一個由服務(wù)端匯集的對象,包含由 XML-RPC 客戶端發(fā)送來的數(shù)據(jù)。使用該對象可以讓你訪問到 request parameters 以便處理請求。請求處理完成后,發(fā)送一個 Response 返回給客戶端。
下面是一個較為實際的例子,使用 Blogger 的 API。Blogger API 中的一個方法是 getUserInfo(),使用該方法 XML-RPC 客戶端可以發(fā)送用戶名和密碼到服務(wù)器,在服務(wù)器返回的數(shù)據(jù)會包含該特定用戶的信息(昵稱,用戶 ID,Email 地址等等)。下面是處理函數(shù)可能的樣子:
class My_blog extends CI_Controller {
????function getUserInfo($request)
????{
????????$username = 'smitty';
????????$password = 'secretsmittypass';
????????$this->load->library('xmlrpc');
????
????????$parameters?=?$request->output_parameters();
????
????????if?($parameters['1'] != $username AND $parameters['2'] != $password)
????????{
????????????return?$this->xmlrpc->send_error_message('100',?'Invalid?Access');
????????}
????
????????$response?=?array(array('nickname'??=>?array('Smitty','string'),
????????????????????????????????'userid'????=>?array('99','string'),
????????????????????????????????'url'???????=>?array('http://yoursite.com','string'),
????????????????????????????????'email'?????=>?array('jsmith@yoursite.com','string'),
????????????????????????????????'lastname'??=>?array('Smith','string'),
????????????????????????????????'firstname'?=>?array('John','string')
????????????????????????????????),
?????????????????????????'struct');
????????return $this->xmlrpc->send_response($response);
????}
}
注意:
output_parameters() 函數(shù)會檢索一個由相應(yīng)客戶端發(fā)送的索引過的請求參數(shù)數(shù)組。上面的例子中輸出參數(shù)將會是用戶名和密碼。
如果客戶端發(fā)送的用戶名和密碼無效的話,錯誤信息會通過 send_error_message() 函數(shù)返回。
如果操作成功,客戶端會收到包含用戶信息的反饋數(shù)組。
格式化反饋信息
就像 Requests, Responses 必須被格式化為數(shù)組。然而不同于請求信息,反饋信息是只包含一個項的數(shù)組。該項可以是一個包含很多其他數(shù)組的的數(shù)組,但是只有一個主數(shù)組索引,下面是一個反饋信息大概的樣子:
$response = array('Response data', 'array');
但是反饋信息通常包含多個分塊信息。要做到這樣,我們必須把各分塊信息放到他們自己的數(shù)組中,這樣主數(shù)組就始終只有一個數(shù)據(jù)項。這里是一個例子來展示如何達成這樣的效果:
$response = array (
???????????????????array(
?????????????????????????'first_name' => array('John', 'string'),
?????????????????????????'last_name' => array('Doe', 'string'),
?????????????????????????'member_id' => array(123435, 'int'),
?????????????????????????'todo_list' => array(array('clean house', 'call mom', 'water plants'), 'array'),
????????????????????????),
?????????????????'struct'
?????????????????);
注意:上面的數(shù)組被格式化為 struct,這是反饋信息最常見的數(shù)據(jù)類型。
如同請求信息一樣,反饋信息可以是七種數(shù)據(jù)類型中的一種,參見 數(shù)據(jù)類型 一節(jié)。
發(fā)送出錯反饋
如果你需要發(fā)送給客戶端一個出錯反饋,你會使用到下面的代碼:
return $this->xmlrpc->send_error_message('123', 'Requested data not available');
第一個參數(shù)是出錯編號,第二個參數(shù)是出錯信息。
創(chuàng)建你自己的客戶端與服務(wù)端
為了幫助理解這些,讓我們創(chuàng)建兩個控制器來演示 XML-RPC 的客戶端和服務(wù)端。你將用客戶端來發(fā)送一個請求到服務(wù)端并從服務(wù)端收到一個反饋。
客戶端
使用編輯器創(chuàng)建一個控制器,起名為 xmlrpc_client.php。在這個控制器中,粘貼以下的代碼并保存到 applications/controllers/ 目錄:
注意:在上面的代碼中我們使用了 "url" 輔助函數(shù),你可以在輔助函數(shù)頁面找到更多信息。
服務(wù)端
使用編輯器創(chuàng)建一個控制器,起名為 xmlrpc_server.php。在這個控制器中,粘貼一下代碼并保存到 applications/controllers/ 目錄:
試試吧!
現(xiàn)在像下面的鏈接這樣訪問你的站點:
example.com/index.php/xmlrpc_client/
現(xiàn)在你應(yīng)該能看到你發(fā)送到服務(wù)端的信息,并且被返回給了你。
在客戶端,你發(fā)送了一條消息 ("How's is going?") 到服務(wù)端,隨著一個請求發(fā)送到 "Greetings" 方法。服務(wù)端收到這個請求并映射到 "process" 函數(shù),然后把反饋信息返回。
在請求參數(shù)中使用關(guān)聯(lián)數(shù)組
如果你希望在你的方法參數(shù)中使用關(guān)聯(lián)數(shù)組,那么你需要使用 struct 數(shù)據(jù)類型:
$request = array(
?????????????????array(
???????????????????????// Param 0
???????????????????????array(
?????????????????????????????'name'=>'John'
???????????????????????????? ),
?????????????????????????????'struct'
???????????????????????),
???????????????????????array(
?????????????????????????????// Param 1
?????????????????????????????array(
?????????????????????????????????? 'size'=>'large',
???????????????????????????????????'shape'=>'round'
?????????????????????????????????? ),
?????????????????????????????'struct'
???????????????????????)
?????????????????);
$this->xmlrpc->request($request);
你可以在服務(wù)端處理請求信息時檢索關(guān)聯(lián)數(shù)組。
$parameters = $request->output_parameters();
$name = $parameters['0']['name'];
$size = $parameters['1']['size'];
$size = $parameters['1']['shape'];
XML-RPC Function Reference
$this->xmlrpc->server()
Sets the URL and port number of the server to which a request is to be sent:
$this->xmlrpc->server('http://www.sometimes.com/pings.php', 80);
$this->xmlrpc->timeout()
Set a time out period (in seconds) after which the request will be canceled:
$this->xmlrpc->timeout(6);
$this->xmlrpc->method()
Sets the method that will be requested from the XML-RPC server:
$this->xmlrpc->method('method');
Where method is the name of the method.
$this->xmlrpc->request()
Takes an array of data and builds request to be sent to XML-RPC server:
$request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/');
$this->xmlrpc->request($request);
$this->xmlrpc->send_request()
The request sending function. Returns boolean TRUE or FALSE based on success for failure, enabling it to be used conditionally.
$this->xmlrpc->set_debug(TRUE);
Enables debugging, which will display a variety of information and error data helpful during development.
$this->xmlrpc->display_error()
Returns an error message as a string if your request failed for some reason.
echo $this->xmlrpc->display_error();
$this->xmlrpc->display_response()
Returns the response from the remote server once request is received. The response will typically be an associative array.
$this->xmlrpc->display_response();
$this->xmlrpc->send_error_message()
This function lets you send an error message from your server to the client. First parameter is the error number while the second parameter is the error message.
return $this->xmlrpc->send_error_message('123', 'Requested data not available');
$this->xmlrpc->send_response()
Lets you send the response from your server to the client. An array of valid data values must be sent with this method.
$response = array(
?????????????????array(
????????????????????????'flerror' => array(FALSE, 'boolean'),
????????????????????????'message' => "Thanks for the ping!"
?????????????????????)
?????????????????'struct');
return $this->xmlrpc->send_response($response);
數(shù)據(jù)類型
According to the XML-RPC spec there are seven types of values that you can send via XML-RPC:
- int or i4
- boolean
- string
- double
- dateTime.iso8601
- base64
- struct (contains array of values)
- array (contains array of values)
?