A Mutable Log

JSON-RPC

If your HTML5 application requires RPC (remote procedure call) semantics, JSON-RPC is an easy specification to implement.

The implementation below allows sending requests and receiving responses, and leverages JQuery’s custom events to raise notifications (requests sent by server without an id). You’ll need to implement the send function, to send the RPC message to the server. A corresponding receive function should call dispatchMessage to handle a RPC message received from the server.

var nextId = 1;
var messages = new Array();

function Request(method, data) {
    this.method = method;
    // params is a C# keyword hence it is called data
    if (data)
        this.data = data;
}

Request.prototype.execute = function (callback) {
    if (callback) {
        this.id = nextId++;
        messages[this.id] = callback;
    }
    // Implement send so that the request gets sent to a server
    send(JSON.stringify(this));
}

// Whoever receives a stringified message from server must call dispatchMessage
function dispatchMessage(message) {
    var o = JSON.parse(message);

    if (Array.isArray(o)) {
        dispatchBatch(o);
    } else {
        dispatch(o);
    }
}

function dispatchBatch(array) {
    array.forEach(function (message) {
        dispatch(message);
    })
}

function dispatch(message) {
    if (message.method) {
        // request
        $(document).trigger(message.method, message);
    } else {
        // response
        var callback = messages[message.id];
        if (callback) {
            messages = messages.filter(function (elem) {
                return elem.id == message.id; // remove
            });
            callback(message);
        } else {
            console.log("Unknown response " + JSON.stringify(message));
        }
    }
}

The following code snippet demonstrates how to handle a notification called foo, sent by a server

$(document).on("foo", function (e, request) {
    // do something with request.data
});

The following code snippet demonstrates how to send a new request for a method called bar, and handle the corresponding response

// data is some object that will be stringified
var request = new Request("bar", data);
request.execute(function (response) {
    // do something with response.error or response.result
})

I’ll leave the server-side code to handle JSON-RPC as an exercise to the reader. I’ve intentionally modified the params attribute in JSON-RPC spec to data, because the former is a reserved keyword in C#. Using reserved keywords with dynamic programming capabilities of libraries such as JSON.NET causes compilation errors.