XML-RPC and XML-RPC Server Classes

XML-RPC 클래스를 이용하시면 다른 서버로 요청을 보낼수 있으며 여러분의 XML-RPC 서버를 설정하여 요청을 받을수도 있습니다.

XML-RPC란 무엇인가 What is XML-RPC?

간단히 말해 XML로 인터넷을 통해 두 컴퓨터가 통신하는 방법입니다.먼저 클라이언트라는 컴퓨터가 XML-RPC 요청 을 서버라고 하는 다른컴퓨터에 에 보냅니다. 일단 서버가 요청을 받아들이고 처리하면, 다시 응답 을 클라이언트로 보내게 됩니다.

예를 들어, MetaWeblog API 를 사용할 때, XML-RPC 클라이언트(보통 데스크탑 게시(publishing) 툴)는 여러분의 사이트에서 돌아가고 있는 XML-RPC 서버에 요청을 보내게 됩니다. 이 요청은 새로운 웹로그 입력이거나,기존 웹로그의 수정에 대한 요청일 것입니다. XML-RPC 서버가 이 요청을 수신하면 서버는 어떤 클래스/함수 가 요청을 처리할지를 결정합니다. 처리가 완료되면, 서버는 응답메세지를 되돌려주게 됩니다.

좀 더 자세한 정의를 보시려면, XML-RPC 사이트를 참고하세요.

XML-RPC 클래스 사용하기 Using the XML-RPC Class

클래스 초기화 Initializing the Class

대부분의 다른 클래스들 처럼 XML-RPC 와 XML-RPCS 클래스도 컨트롤러에서 $this->load->library 함수를 통해 초기화 됩니다:

Xml RPC 클래스를 로드하려면 아래와 같이 합니다:

$this->load->library('xmlrpc');

일단 로드되면 xml-rpc 라이브러리는 다음과 같이 사용할 수 있습니다: $this->xmlrpc

XML-RPC 서버클래스는 아래와 같이 합니다:

$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');

일단 로드되면, xml-rpcs 라이브러리 객체는 다음과 같이 사용할 수 있습니다: $this->xmlrpcs

Note

XML-RPC 서버클래스를 사용할 때는 XML-RPC 클래스와 XML-RPC 서버클래스 둘 다 로드해야 합니다.

XML-RPC 요청 보내기 Sending XML-RPC Requests

요청을 XML-RPC 서버에 보내려면 다음 정보를 먼저 정의해야 합니다:

  • 서버의 URL
  • 서버에서 호출하고자 하는 메소드
  • 요청 데이터(아래에서 설명함 ).

아래는 간단한 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();
}

설명 Explanation

위 코드에서, XML-RPC 클래스를 초기화하고, 서버 URL과 호출한 메소드(weblogUpdates.ping)를 설정합니다.전송할 요청(이 경우, 제목과 여러분 사이트URL)을 배열에 넣고 request() 함수를 사용하여 합칩니다. 마지막으로, 전체 요청을 보냅니다. 만약 send_request() 메소드가 false를 리턴하면 XML-RPC 서버로부터 되돌아오는 에러 메세지를 표시하게 됩니다.

요청 해부 Anatomy of a Request

XML-RPC 요청(request) 는 간단히 말하면 XML-RPC 로 보내는 데이터 입니다. 요청을 구성하는 조각데이터들은 요청파라미터(request parameter)로써 참조됩니다. 위 예제에서는 두 개의 파라미터를 사용했습니다: 제목과 여러분 사이트URL가 그것입니다. XML-RPC 서버가 여러분의 요청을 받으면, 필요한 파라미터도 같이 넘어올 것이라고 기대합니다.

요청파라미터는 반드시 배열에 담아야하며, 각 파라미터는 7가지의 데이터타입(strings, numbers, dates, etc.)중 하나로 해야 합니다. 만약 파라미터가 문자열(string) 타입이 아니라면, 요청에 데이터타입을 포함해야 합니다.

아래는 3개의 파라미터 설정 예제입니다:

$request = array('John', 'Doe', 'www.some-site.com');
$this->xmlrpc->request($request);

만약 파라미터가 문자열(string)타입이 아니라면, 아래와 같이 배열내에 다시 배열을 삽입하고 데이터형을 같이 설정해주셔야 합니다:

$request = array(
        array('John', 'string'),
        array('Doe', 'string'),
        array(FALSE, 'boolean'),
        array(12345, 'int')
);
$this->xmlrpc->request($request);

데이터타입 (Data Types) 섹션을 보시면 모든 데이터타입목록을 확인하실 수 있습니다.

XML-RPC 서버 생성 Creating an XML-RPC Server

XML-RPC 서버는 교통경찰같이 동작합니다. 요청을 기다리고 들어온 요청에 대해서는 적합한 함수로 연결(redirect) 해 줍니다.

XML-RPC 서버를 생성하려면,요청을 받을 컨트롤러에서 XML-RPC 서버 클래스를 초기화하고 들어온 요청을 적절한 클래스/함수로 연결하는 규칙을 배열로 설정해야 합니다.

아래 예제를 보세요:

$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();

위 예제는 서버가 받아들일 두 가지 요청처리 메소드를 정의하고 있습니다. 요청을 받는 메소드는 배열의 왼쪽에 있습니다. 둘중 하나의 요청이 들어오면, 오른쪽에 있는 클래스/함수로 매핑됩니다.

‘object’ 키는 실제객체(instantiated class object)를 전달하는 특별한 키입니다. 매핑하고자 하는 메소드가 CodeIgniter 부모객체(super object)의 일부가 아닐때 필요합니다.

다시말해, XML-RPC 클라이언트가 new_post 메소드에 대한 요청을 전송하면, 여러분의 서버는 My_blog 클래스를 로드한 후 new_entry 함수를 호출합니다.update_post 메소드에 대한 요청이 들어오면, 서버는 My_blog 클래스를 로드한 후 update_entry() 함수를 호출 합니다.

위 예제의 함수이름은 임의로 지은 것입니다.

서버 클래스를 초기화 할 때 사용할 수 있는 두 개의 추가 설정 키가 있습니다.debug 를 TRUE 로 설정하면, 디버깅이 활성화 되며 xss_clean 를 FALSE 로 두면 전송하는 데이터에 Security 라이브러리의 xss_clean() 함수를 적용하지 않습니다.

서버 요청 처리 Processing Server Requests

XML-RPC 서버가 요청을 받고 클래스/메소드 를 로드하면, 클라이언트로부터 받은 데이터를 그 메소드로 넘겨주게 됩니다.

위의 예제에서 new_post 메소드가 요청되면, 서버는 아래와 같은 형태의 클래스가 있을것이라고 기대합니다:

class My_blog extends CI_Controller {

        public function new_post($request)
        {

        }
}

$request 변수는 서버에서 구성(compile)된 객체이며,클라이언트로부터 전달된 데이터를 포함하고 있습니다.요청을 처리하기 위해 요청파라미터(request parameters) 에 접근하려면 이 객체를 사용합니다. 처리가 끝나면 여러분은 응답(Response)을 클라인트에게 되돌려줄것입니다.

아래는 Blogger API를 사용한 실제 예제입니다. getUserInfo() 는 Blogger API 의 한 메소드 입니다. 이 메소드를 이용하여, XML-RPC 클라이언트는 서버로 사용자이름과 암호를 전송하고 특정사용자에 대한 정보(nickname, user ID, email address, 등.)를 받습니다. 아래예제는 그 과정을 보여줍니다:

class My_blog extends CI_Controller {

        public function getUserInfo($request)
        {
                $username = 'smitty';
                $password = 'secretsmittypass';

                $this->load->library('xmlrpc');

                $parameters = $request->output_parameters();

                if ($parameters[1] != $username && $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() 함수는 클라이언트가 전송한 파라미터에 대응하는 배열을 복원(retrieve)해 냅니다. 위 예제애서, 출력 파라미터(output parameters)는 username, password가 될 것입니다.

만약 클라이언트가 전송한 username, password 가 틀린 것이라면 send_error_message() 함수를 통해 에러 메세지를 리턴합니다.

응답 구성 Formatting a Response

요청(Requests) 이나 응답(Responses)은 반드시 배열로 구성되어야 합니다. 그러나, 요청(request)과는 달리 응답(response)은 단일 아이템을 포함한 배열입니다. 이 아이템은 여러 배열을 포함한 배열일 수 있지만, 단 하나의 배열인덱스만을 포함할 수 있습니다. 다시 말하면, 아래예제가 기본적인 형태입니다:

$response = array('Response data', 'array');

응답(Response)은 보통 여러가지 정보를 포함합니다. 그렇게 하기 위해서는 아래와 같이 단일 배열안애 여러가지 정보가 들어간 하위배열을 구성하시면 됩니다:

$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'
);

위 배열은 struct로 구성되어 있습니다. 이런형태는 가장 일반적으로 사용하는 응답구성입니다.

요청과 마찬가지로 응답또한 7가지 데이터타입(Data Types)을 사용할 수 있습니다.

에러응답 전송하기 Sending an Error Response

클라이언트에게 에러를 전송해야 할 경우 아래와 같이 하시면 됩니다:

return $this->xmlrpc->send_error_message('123', 'Requested data not available');

첫 번째 파라미터는 에러 번호이고, 두 번째 파라미터는 메세지 입니다.

클라이언트와 서버 만들기 Creating Your Own Client and Server

지금까지의 설명에 대한 이해를 돕기위해서 XML-RPC 클라이언트 와 서버를 직접 만들어봅시다.

클라이언트 The Client

Xmlrpc_client.php 라는 파일을 만드신후 아래 코드를 삽입하고 applications/controllers/ 폴더에 저장합니다:

<?php

class Xmlrpc_client extends CI_Controller {

        public function index()
        {
                $this->load->helper('url');
                $server_url = site_url('xmlrpc_server');

                $this->load->library('xmlrpc');

                $this->xmlrpc->server($server_url, 80);
                $this->xmlrpc->method('Greetings');

                $request = array('How is it going?');
                $this->xmlrpc->request($request);

                if ( ! $this->xmlrpc->send_request())
                {
                        echo $this->xmlrpc->display_error();
                }
                else
                {
                        echo '<pre>';
                        print_r($this->xmlrpc->display_response());
                        echo '</pre>';
                }
        }
}
?>

Note

위 예제에서“url helper” 를 사용하였습니다. 헬퍼 함수(Helpers Functions) 페이지를 보시면 자세한 정보가 있습니다.

서버 The Server

xmlrpc_server.php파일을 만드신후 아래 코드를 삽입하고 applications/controllers/ 폴더에 저장합니다:

<?php

class Xmlrpc_server extends CI_Controller {

        public function index()
        {
                $this->load->library('xmlrpc');
                $this->load->library('xmlrpcs');

                $config['functions']['Greetings'] = array('function' => 'Xmlrpc_server.process');

                $this->xmlrpcs->initialize($config);
                $this->xmlrpcs->serve();
        }


        public function process($request)
        {
                $parameters = $request->output_parameters();

                $response = array(
                        array(
                                'you_said'  => $parameters[0],
                                'i_respond' => 'Not bad at all.'
                        ),
                        'struct'
                );

                return $this->xmlrpc->send_response($response);
        }
}

시도해봅시다 Try it!

자 이제 아래와 같은 url 로 접근해 봅시다:

example.com/index.php/xmlrpc_client/

여러분이 서버로 보낸메세지와 응답을 보실 수 있습니다.

클라이언트는 “How’s is going?” 메세지를 “Greetings” 메소드 요청과 함께 서버로 보냅니다. 서버는 요청을 받아들인 후 process() 함수로 매핑하여 응답을 돌려줍니다.

요청 파라미터로 연관배열 사용하기 Using Associative Arrays In a Request Parameter

만약 메소드의 파라미터에 연관배열을 사용하고자 한다면 struct 데이터타입을 사용하셔야 합니다:

$request = array(
        array(
                // Param 0
                array('name' => 'John'),
                'struct'
        ),
        array(
                // Param 1
                array(
                        'size' => 'large',
                        'shape'=>'round'
                ),
                'struct'
        )
);

$this->xmlrpc->request($request);

서버에서 요청을 처리할 때 연관배열을 아래와 같이 사용(retrieve)할 수 있습니다.

$parameters = $request->output_parameters();
$name = $parameters[0]['name'];
$size = $parameters[1]['size'];
$shape = $parameters[1]['shape'];

테이터 타입 Data Types

XML-RPC 스펙에 따르면 당신이 XML-RPC를 통해 보낼 수 있는 값의 일곱 종류가 있습니다 :

  • int or i4
  • boolean
  • string
  • double
  • dateTime.iso8601
  • base64
  • struct (contains array of values)
  • array (contains array of values)

클래스 레퍼런스 Class Reference

class CI_Xmlrpc
initialize([$config = array()])
인수:
  • $config (array) – Configuration data
반환형:

void

XML-RPC 라이브러리를 초기화 합니다. 설정을 포함하는 연관 배열을 받아들입니다.

server($url[, $port = 80[, $proxy = FALSE[, $proxy_port = 8080]]])
인수:
  • $url (string) – XML-RPC server URL
  • $port (int) – Server port
  • $proxy (string) – Optional proxy
  • $proxy_port (int) – Proxy listening port
반환형:

void

요청을 보낼 서버의 URL과 포트번호를 설정합니다:

$this->xmlrpc->server('http://www.sometimes.com/pings.php', 80);

기본적인 HTTP 인증도 지원됩니다, 서버 URL에 추가하세요:

$this->xmlrpc->server('http://user:pass@localhost/', 80);
timeout($seconds = 5)
인수:
  • $seconds (int) – Timeout in seconds
반환형:

void

요청이 취소될 타임아웃 기간을 초단위로 설정합니다:

$this->xmlrpc->timeout(6);
method($function)
인수:
  • $function (string) – Method name
반환형:

void

XML-RPC 서버로부터 요청될 메소드를 설정합니다:

$this->xmlrpc->method('method');

method 는 메소드의 이름입니다.

request($incoming)
인수:
  • $incoming (array) – Request data
반환형:

void

데이터배열을 받아서 서버로 전송될 데이터를 구성합니다:

$request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/');
$this->xmlrpc->request($request);
send_request()
반환값:TRUE on success, FALSE on failure
반환형:bool

요청을 보내는 함수 입니다. 성공여부에 따라서 TRUE나 FALSE를 리턴합니다.

display_error()
반환값:Error message string
반환형:string

요청 실패에 대한 에러 메세지를 문자열로 리턴합니다.

echo $this->xmlrpc->display_error();
display_response()
반환값:Response
반환형:mixed

요청을 하면 서버는 응답을 리턴합니다. 응답은 일반적으로 연관배열입니다.

$this->xmlrpc->display_response();
send_error_message($number, $message)
인수:
  • $number (int) – Error number
  • $message (string) – Error message
반환값:

XML_RPC_Response instance

반환형:

XML_RPC_Response

이 함수를 이용하시면 서버에서 클라이언트로 에러 메세지를 전송할 수 있습니다. 첫 번째 파라미터는 에러번호, 두 번째 파라미터는 에러 메세지 입니다.

return $this->xmlrpc->send_error_message(123, 'Requested data not available');