This is a Ruby implementation of the Hessian Binary Web Service Protocol. This is the Github version of the Ruby Hessian client originating from RubyForge, with patches and updates.
Here's the description from the Hessian site at http://www.caucho.com/hessian.
The Hessian binary web service protocol makes web services usable without requiring a large framework, and without learning yet another alphabet soup of protocols. Because it is a binary protocol, it is well-suited to sending binary data without any need to extend the protocol with attachments.
Please consult the Hessian home page or the Hessian 1.0.2 specification for more information.
The Hessian Ruby Client acts as a proxy for remote calls to Hessian services.
Hessian services are identified by URI's and the Ruby Hessian Client supports the http and https schemes. A call to a Hessian service is made like a regular method invocation in Ruby, and the Ruby Hessian Client will transparently serialize and deserialize to and from Ruby types.
Hessian's object serialization has 13 types, and the following mappings are used in the Ruby Hessian Client.
The 9 primitive types:
- binary:: Hessian::Binary
- boolean:: TrueClass or FalseClass
- date:: Time
- double:: Float
- int:: Integer
- long:: Integer
- remote:: Not implemented!
- string:: String
- xml:: String
- symbol:: String
The 2 combining types:
- list:: Array
- map:: Hash
Finally, the 2 special constructs:
- null:: NilClass
- ref:: The type referenced
The combining Hessian types can be given an explicit type understood by the service. This can be used to specify that a list only contain strings for example, or more importantly - this is how to serialize custom types. A custom type in this context is all types not conforming to the 13 types above, such as your own objects etc.
Custom types are serialized using the map with an explicit type specified and the underlying Ruby type must be a Hash. To specifiy an explicit type wrap the object in a Hessian::TypeWrapper or create the method +hessian_type+ on that object. See the examples below.
The Ruby Hessian Client will automatically convert instances of the Struct class to a Hash but for all other custom types you must create the conversion.
When a service reply (i.e. the return type of the method called) is a custom type, the Ruby Hessian Client will always return a Hash since the type returned might be unknown in Ruby. You may then convert that Hash to suite your needs.
Errors in a call to a Hessian service will result in a fault that is wrapped as a Hessian::HessianException.
To create a Hessian::HessianClient instance:
client = Hessian::HessianClient.new('http://localhost:8080/echo')
To specify a user and a password for basic authentication:
client.user, client.password = 'foo', 'bar'
To create a Hessian::HessianClient using a proxy:
proxy = { :host => 'proxy.foo.bar', :port => '80' }
client = Hessian::HessianClient.new('http://localhost:8080/echo, proxy)
The valid symbol keys for the proxy hash are: [:host] Proxy host [:port] Proxy port [:user] Proxy user [:password] Proxy password
Let's say that the service bound to echo is the following:
class Echo
def echo(msg)
"Echo reply: #{msg}"
end
end
Then invoking the service call echo:
client.echo('hessian') => "Echo reply: hessian"
To specify an explicitly typed list as a Java string array for example (where foo is a method on the Java service used):
list = %w(one two three)
client.foo(Hessian::TypeWrapper.new('[string', list))
or
list = %w(one two three)
def list.hessian_type
'[string'
end
client.foo(list)
Let's pretend that we want to call a Java service that has the following interface:
public interface PersonService implements Serializable {
public Person addPerson(Person person);
}
and where the Person is defined as (could be a JavaBean as well):
public interface Person implements Serializable {
public int age;
public String name;
}
Person is a custom type so we need to send a Hash with an explicit type specified:
person = { 'age' => 32, 'name' => 'Christer Sandberg' }
reply = client.addPerson(Hessian::TypeWrapper.new('Person', person))
The Ruby Hessian Client will automatically convert a Struct to a Hash so the following will also work:
person = Struct.new(:age, :name)[32, 'Christer Sandberg']
class << person
def hessian_type
'Person'
end
end
reply = client.addPerson(person)
The result from these invocations would be a Hash:
reply => { 'age' => 32, 'name' => 'Christer Sandberg' }