<document>
  <header>
    <product>resin</product>
    <resin-2.0>$article/hessian-messaging.xtp</resin-2.0>
    <title>Hessian Messaging</title>
    <description>
      <p>The Hessian binary web service protocol can
        provide a messaging service layered on top of its
        RPC call.  The messaging service itself is based on the standard
        Hessian RPC call, so Hessian itself has no need to become more
        complicated.</p>

      <p>Each hop the message takes uses a simple <code/send/> method to the
        next server in line.  The receiving service might be the final
        destination or it might choose to send the message to another server,
        making another hop.  This architecture is essentially the same as the
        standard SMTP mail architecture.  SMTP is custom protocol
        for each hop while RFC-822 specifies the meaning of the mail
        headers.</p>

      <p>We'll just be discussing the hop protocol,
        i.e. the SMTP replacement.  Any definition of the end-to-end headers
        and routing would be built on top of the basic Hessian messaging.</p>
      
      <p>This discussion shows that Hessian's RPC mechanism is sufficient
        for handling messaging, without introducing any extra complications to
        the Hessian protocol itself.  By choosing a layered protocol model, each
        protocol layer can be simple independent of the others.</p>
      
    </description>
  </header>

  <body>
    <summary/>

<section title="Messaging Service">

<p>The message service sends a message from the client to the server.
When you strip away all other complications, that's all messaging does.</p>

<p>The message service method is simple.  It consists of a single
method <code/send/> with two arguments: <code/headers/> and <code/message/>.
<code/headers/> contain message routing information.  <code/message/>
contains the message itself.</p>

<example title="API">
package com.caucho.services.message;

public interface MessageSender {
  public void send(java.util.HashMap headers, Object message)
    throws MessageServiceException;
}
</example>

</section>

<section title="Point-to-Point Messaging">

<p>The simplest messaging service receives text message to
a URL.  With that messaging service, only the message object is used and
the headers are ignored.  Many applications only need the most basic
messaging protocol.  Until the application needs messages to be
forwarded and to have many middle servers, the simple use
case is sufficient.</p>

<p>The message service URL is the message destination.
This example might use <var/http://foo.com/hessian/message/test-bean/>.
Since this sample service ignores the headers, there's no forwarding
of the message.</p>

<example title="Hessian call to send Hello, world message">
c x01 x00                -- hessian call
  m x00 x04 send         -- the send method
  N                      -- null headers
  S x00 x0c Hello, world -- string message
z                        -- end of request
</example>

<p>The Hessian packet does not need to contain the URL, since that's
specified in the containing enveloper.  For example, when using
Hessian with HTTP, the HTTP request will specify the URL of the
Hessian service.</p>

<section title="Sending a message from a Java client">

<p>An application can use any Java client which can send Hessian to the
message service.  The standard HessianProxyFactory could be used.</p>

<p>Calling the messaging service from Java uses HessianProxyFactory
to create a client proxy.  Once the client is available, the
application can just start sending messages.</p>

<example title="Calling from Java">
String url = "http://foo.com/hessian/message/test-bean";

HessianProxyFactory factory = new HessianProxyFactory();
MessageSender sender;
sender = (MessageSender) factory.create(MessageSender.class, url);

sender.send(null, "Hello");
</example>

</section>

<section title="Calling from a Python client">

<p>Since Hessian is language-independent, any scripting languages with
a Hessian implementation can send to a messaging service.
For example, the <a href="http://www.caucho.com/hessian">Python
Hessian library</a> allows Python to send a message to a Hessian
message service.</p>

<example title="Calling from Python">
import hessianlib;

proxy = Hessian("http://foo.com/hessian/message/test-bean")
proxy.send(None, "hello")
</example>

</section>

<section title="Implementing the Service as an EJB Message Bean">

<p>Resin-Enterprise uses the Hessian MessageSender as a
JMS (Java Message Service) protocol.  So applications can use
EJB MessageBeans to implement a message service.</p>

<example title="MessageBean implementation">
package test.hello;

import javax.ejb.*;
import javax.jms.*;

public class MyMessageBean implements MessageDrivenBean, MessageListener {
  public void setMessageDrivenContext(MessageDrivenContext cxt)
  {
  }

  public void ejbCreate()
  {
  }

  public void onMessage(Message msg)
  {
    try {
      TextMessage textMessage = (TextMessage) msg;

      String text = textMessage.getText();

      System.out.println("MESSAGE: " + text);
    } catch (JMSException e) {
    }
  }

  public void ejbRemove()
  {
  }
}
</example>

<p>The EJB deployment descriptor and the EJB server configuration are
implemented in the usual way.  In this case, the bean name would be
<var/test-bean/>.</p>

<example title="web.xml entries to configure the EJB server">
&lt;-- configure the EJB server -->
&lt;resource-ref>
  &lt;res-ref-name>java:comp/env/cmp&lt;/res-ref-name>
  &lt;class-name>com.caucho.ejb.EJBService&lt;/class-name>
&lt;/resource-ref>

&lt;-- configure the Hessian protocol -->
&lt;servlet-mapping>
  &lt;url-pattern>/hessian/*&lt;/url-pattern>
  &lt;servlet-name>com.caucho.ejb.hessian.HessianServlet&lt;/servlet-name>
&lt;/servlet-mappin>
</example>

</section>

</section>

<section title="Messaging with Routing">

<p>Routing parameters are contained in the headers map.
For example, Java's messaging service (JMS) defines a number
of routing headers.  These headers could be used for more sophisticated
mail routing than point to point.</p>

<p>Defining the routing headers is beyond the aim of this page.  The
important point to note is that the routing protocol is built on top
of the Hessian messaging service which is built on Hessian.
Hessian itself does not need to be complicated with the routing headers.</p>

</section>

<section title="Conclusion">

<p>In some sense, this protocol is too simple.  That's the point.  By
designing the messaging protocol as a layered system, each layer can
be simple.  So a simple messaging service will be easy, and
complicated messaging routing services are still possible.</p>

<ul>
<li>Hessian can remain a simple RPC protocol with no complicated
routing headers.
<li>The messaging service API can remain trivial so simple scripting
language clients can use it.
<li>Sophisticated routing protocols can be built on top of the
messaging by properly defining the headers.
</ul>

</section>

  </body>
</document>
