haXe remoting

The yaws_rpc module has a haXe remoting adapter that enables Yaws to respond to respond to RPC requests from a client written in haXe. haXe is a versatile open source language that compiles to Flash, Javascript and NekoVM. For more information on haXe, visit www.haxe.org/intro.

Implementing the server side of a haXe remoting interaction in Yaws is very similar to the one described in the Ajax/JSON RPC page. Most of the action takes place behind the scenes inside the the yaws_rpc module. The same types (array, struct, number and string) work for haXe remoting as for JSON RPC. There are just a few new things to keep in mind when using haXe remoting:

  1. Class objects and enums work with standard haXe remoting, but are not supported in Yaws. You should therefore rely on anonymous objects and signatures when designing your haXe remoting calls.

  2. A Yaws RPC handler can "throw an exception" by returning {exception, Obj}, where Obj is any valid haXe remoting value.

  3. haXe remoting has a few extra values, expressed by the atoms 'infinity', 'neg_infinity' and 'nan', corresponding to infinity, negative infinity and 'not a number.'

Following is an example demonstrating the use of haXe remoting in yaws. The first code segment is the haXe client code, which invokes the 'echo' method in haxe_sample.yaws and displays the result:

// To try this sample out using haXe and neko,
// save this file as Application.hx and run the following to compile it:
// haxe Application -neko Application.n -main Application.hx
// and the following to execute it:
// neko Application.n
class Application {

  public static function main():Void {
    var URL = "http://localhost:8000/haxe_sample.yaws";
    var cnx = haxe.remoting.HttpAsyncConnection.urlConnect(URL);
    cnx.setErrorHandler( function(err) {
      trace("Exception : " + Std.string(err));
    } );
    var a = {a:"foo", b:"bar", c:[1,2,3]};
    var b = "hello, Erlang!";
    cnx.echo.call([a, b], display);
    cnx.failure.call([a, b], display);
  }

  static function display(v) {
    trace(v);
  }
}

On the server side, we have the file haxe_sample.yaws with the following code:

<erl module=haxe_sample>
-export([respond/2]).

out(A) ->
        A1 = A#arg{state = {new_state, "alive and kicking"}},
        yaws_rpc:handler(A1, {haxe_sample, respond}).

respond(State, {call, failure, Value} = _Request) ->
        { false, { error, { struct, [ { message, "Failure" }, { code, 500 } ] } } };

respond(State, {call, echo, Value} = _Request) ->
        {new_state, StateVal} = State,
        {array, [First, Second]} = Value,
        Response =
                {response,
                {struct, [
                        {you_sent_first, First},
                        {btw, "Hello haXe!"},
                        {also, {array, ["take", "this", 4, "array"]}},
                        {my_state_is, StateVal}
                        ]
                }},
            {true, 0, null, Response}.
</erl>

The two important lines on the server side are:

  1. yaws_rpc:handler(A1, {haxe_sample, respond}).
  2. respond(State, {call, echo, Value} = _Request)

The first line tells Yaws to forward all RPC calls (this includes both haXe remoting and JSON RPC calls -- remember that the yaws_rpc module handles both RPC mechanisms transparently) to the "respond" function in the "haxe_sample" module.

The second line tells Yaws to invoke this 'respond' function when the client requests the method 'echo', while passing the new state variable as the first argument to 'respond'. You should duplicate this line for every RPC method you wish to implement, replacing 'echo' with the method's name.

yaws_rpc optionally handles sessions for both JSON RPC and haXe remoting. To use sessions, invoke yaws_rpc:handler_session as shown in the JSON RPC documentation page.

If the response is in the form of {exception, Obj}, where Obj is any valid haXe remoting type, then the haXe client will invoke the 'onError' handler, with Obj passed as the parameter.

As with JSON RPC, both request and response values can be composed of nested tuples of the form

{array, [Obj,...]}

and/or

{struct, [{prop, Val}...]}

Now go have fun! :)

Valid XHTML 1.0!