# xmlrpc/client.rb

Copyright (C) 2001, 2002 by Michael Neumann (neumann@s-direktnet.de)

Released under the same term of license as Ruby.

# Classes

- XMLRPC::Client
- XMLRPC::Client::Proxy

# XMLRPC::Client

## Synopsis

    require "xmlrpc/client"

    server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)
    begin
      param = server.call("michael.add", 4, 5)
      puts "4 + 5 = #{param}"
    rescue XMLRPC::FaultException => e
      puts "Error:"
      puts e.faultCode
      puts e.faultString
    end

or

    require "xmlrpc/client"

    server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)
    ok, param = server.call2("michael.add", 4, 5)
    if ok then
      puts "4 + 5 = #{param}"
    else
      puts "Error:"
      puts param.faultCode
      puts param.faultString
    end

## Description

Class `XMLRPC::Client` provides remote procedure calls to a XML-RPC server. After setting the connection-parameters with XMLRPC::Client.new which creates a new `XMLRPC::Client` instance, you can execute a remote procedure by sending the call or call2 message to this new instance. The given parameters indicate which method to call on the remote-side and of course the parameters for the remote procedure.

## Class Methods

`XMLRPC::Client.new( host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, user=nil, password=nil, use_ssl=false, timeout =nil)`

  Creates an object which represents the remote XML-RPC server on the given host host. If the server is CGI-based, path is the path to the CGI-script, which will be called, otherwise (in the case of a standalone server) path should be `"/RPC2"`. port is the port on which the XML-RPC server listens. If proxy_host is given, then a proxy server listening at proxy_host is used. proxy_port is the port of the proxy server.

  Default values for host, path and port are 'localhost', '/RPC2' and '80' respectively using SSL '443'.

  If user and password are given, each time a request is send, a Authorization header is send. Currently only Basic Authentification is implemented no Digest.

  If use_ssl is set to `true`, comunication over SSL is enabled. Note, that you need the SSL package from RAA installed.

  Parameter timeout is the time to wait for a XML-RPC response, defaults to 30.

`XMLRPC::Client.new2( uri, proxy=nil, timeout=nil)`

uri

  URI specifying protocol (http or https), host, port, path, user and password. Example: https://user:password@host:port/path

proxy

  Is of the form "host:port".

timeout

  Defaults to 30.

`XMLRPC::Client.new3( hash={} )`

  Parameter hash has following case-insensitive keys:

  - host
  - path
  - port
  - proxy_host
  - proxy_port
  - user
  - password
  - use_ssl
  - timeout

  Calls XMLRPC::Client.new with the corresponding values.

## Instance Methods

`XMLRPC::Client#call( method, *args )`

  Invokes the method named method with the parameters given by args on the XML-RPC server. The parameter method is converted into a `String` and should be a valid XML-RPC method-name. Each parameter of args must be of one of the following types, where `Hash`, `Struct` and `Array` can contain any of these listed types:

  - `Fixnum`, `Bignum`
  - `TrueClass`, `FalseClass` (`true`, `false`)
  - `String`, `Symbol`
  - `Float`
  - `Hash`, `Struct`
  - `Array`
  - `Date`, `Time`, `XMLRPC::DateTime`
  - `XMLRPC::Base64`
  - A Ruby object which class includes XMLRPC::Marshallable (only if Config::ENABLE_MARSHALLABLE is `true`). That object is converted into a hash, with one additional key/value pair "___class___" which contains the class name for restoring later that object.

  The method returns the return-value from the RPC *1. The type of the return-value is one of the above shown, only that a `Bignum` is only allowed when it fits in 32-bit and that a XML-RPC dateTime.iso8601 type is always returned as a `XMLRPC::DateTime` object and a `Struct` is never returned, only a `Hash`, the same for a `Symbol`, where always a `String` is returned. A `XMLRPC::Base64` is returned as a `String` from xmlrpc4r version 1.6.1 on.

  If the remote procedure returned a fault-structure, then a `XMLRPC::FaultException` exception is raised, which has two accessor-methods `faultCode` and `faultString` of type `Integer` and `String`.

`XMLRPC::Client#call2( method, *args )`

  The difference between this method and call is, that this method do not raise a `XMLRPC::FaultException` exception. The method returns an array of two values. The first value indicates if the second value is a return-value (`true`) or an object of type `XMLRPC::FaultException`. Both are explained in call.

`XMLRPC::Client#multicall( *methods )`

  You can use this method to execute several methods on a XMLRPC server which supports the multi-call extension. Example:

      s.multicall(
        ['michael.add', 3, 4],
        ['michael.sub', 4, 5]
      )
      # => [7, -1]

`XMLRPC::Client#multicall2( *methods )`

  Same as XMLRPC::Client#multicall, but returns like XMLRPC::Client#call2 two parameters instead of raising an `XMLRPC::FaultException`.

`XMLRPC::Client#proxy( prefix, *args )`

  Returns an object of class `XMLRPC::Client::Proxy`, initialized with prefix and args. A proxy object returned by this method behaves like XMLRPC::Client#call, i.e. a call on that object will raise a `XMLRPC::FaultException` when a fault-structure is returned by that call.

`XMLRPC::Client#proxy2( prefix, *args )`

  Almost the same like XMLRPC::Client#proxy only that a call on the returned `XMLRPC::Client::Proxy` object behaves like XMLRPC::Client#call2, i.e. a call on that object will return two parameters.

`XMLRPC::Client#call_async(...)`
`XMLRPC::Client#call2_async(...)`
`XMLRPC::Client#multicall_async(...)`
`XMLRPC::Client#multicall2_async(...)`
`XMLRPC::Client#proxy_async(...)`
`XMLRPC::Client#proxy2_async(...)`

  In contrast to corresponding methods without "_async", these can be called concurrently and use for each request a new connection, where the non-asynchronous counterparts use connection-alive (one connection for all requests) if possible.

  Note, that you have to use Threads to call these methods concurrently. The following example calls two methods concurrently:

      Thread.new {
        p client.call_async("michael.add", 4, 5)
      }

      Thread.new {
        p client.call_async("michael.div", 7, 9)
      }

`XMLRPC::Client#timeout`
`XMLRPC::Client#user`
`XMLRPC::Client#password`

  Return the corresponding attributes.

`XMLRPC::Client#timeout= (new_timeout)`
`XMLRPC::Client#user= (new_user)`
`XMLRPC::Client#password= (new_password)`

  Set the corresponding attributes.

`XMLRPC::Client#set_writer( writer )`

  Sets the XML writer to use for generating XML output. Should be an instance of a class from module `XMLRPC::XMLWriter`. If this method is not called, then `XMLRPC::Config::DEFAULT_WRITER` is used.

`XMLRPC::Client#set_parser( parser )`

  Sets the XML parser to use for parsing XML documents. Should be an instance of a class from module `XMLRPC::XMLParser`. If this method is not called, then `XMLRPC::Config::DEFAULT_PARSER` is used.

# XMLRPC::Client::Proxy

## Synopsis

    require "xmlrpc/client"

    server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80)

    michael  = server.proxy("michael")
    michael2 = server.proxy("michael", 4)

    # both calls should return the same value '9'.
    p michael.add(4,5)
    p michael2.add(5)

## Description

Class `XMLRPC::Client::Proxy` makes XML-RPC calls look nicer! You can call any method onto objects of that class - the object handles `method_missing` and will forward the method call to a XML-RPC server. Don't use this class directly, but use instead method XMLRPC::Client#proxy or XMLRPC::Client#proxy2.

## Class Methods

`XMLRPC::Client::Proxy.new( server, prefix, args=[], meth=:call, delim="." )`

  Creates an object which provides `method_missing`.

  server must be of type `XMLRPC::Client`, which is the XML-RPC server to be used for a XML-RPC call. prefix and delim will be prepended to the methodname called onto this object.

  Parameter meth is the method (call, call2, call_async, call2_async) to use for a RPC.

  args are arguments which are automatically given to every XML-RPC call before the arguments provides through `method_missing`.

## Instance Methods

Every method call is forwarded to the XML-RPC server defined in new.

Note: Inherited methods from class `Object` cannot be used as XML-RPC names, because they get around `method_missing`.

# History

    $Id: client.rb,v 1.48 2002/01/08 23:00:52 michael Exp $

*1 stands for Remote Procedure Call