Running server side processes via JavaScript with Jaxer

Last week I wrote a short introductory article about Aptana's Jaxer. Today I want to follow on from there and introduce one of the new features that has been added in Jaxer 1.0.

Jaxer now provides the ability to quickly and easily execute operating system functions on a web server. This could be put to use for a variety of purposes such as monitoring logfiles with tail or even restarting a server! However, to demonstrate it's usage, I'm going to take a simple example in which we'll attempt to query the webserver for information about it's current status (using the uptime command) and display it to a web client.

view demonstration

example application in action

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
    <title>Jaxer.Process</title>
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <script src="http://code.jquery.com/jquery.js" runat="both"></script>
    <script runat="server-proxy">
      function runUptime() {
        // run the uptime and return the output from STDOUT
        return Jaxer.Process.exec("/usr/bin/uptime");
      }
    </script>
    <script runat="client">
      function uptime() {
        $('#ajaxSpinner').show();
        runUptime.async(updateProcessOutput);
      }
      function updateProcessOutput(res) {
        $('#processOutput').append(res);
        $('#ajaxSpinner').hide();
      }
    </script>
  </head>
  <body>
    <h1>Jaxer.Process</h1>   
    <a href="#" onClick="uptime(); return false;">uptime</a>
    <img id="ajaxSpinner" src="ajax-loader.gif" style="display:none">
    <textarea id="processOutput"></textarea>
  </body>
</html>

Breaking it down

On the server

First, I define a function that will execute uptime on the server.

function runUptime() {
  // run the command and send stdout to the client
  return Jaxer.Process.exec("/usr/bin/uptime");
}

By enclosing this function in <script runat="server-proxy">, I ensure that this function will run on the server, but will also be available to the client. I chose to use the exec() function to run the process synchronously - for longer running processes it is possible to use execAsync() which will run the process in the background. See the Jaxer.Process API docs for details.

On the client

Next, I define the client side functions that will be used to call the function on the server. First, it displays an ajax loading icon to give the user some indication that something is happening. It then then calls the runUptime() function, which runs uptime on the server. This call is made asynchronously so that browser doesn't hang while the process is being executed. I pass the name of a function to be used as a callback as the first argument - updateProcessOutput in this instance.

function uptime() {
  $('#ajaxSpinner').show();
  runUptime.async(updateProcessOutput);
}

The last function, updateProcessOutput() is our callback from above, and simply appends the output from the server into a text area and then hides the ajax loading icon.

function updateProcessOutput(res) {
  $('#processOutput').append(res);
  $('#ajaxSpinner').hide();
}

Despite the simplicity of this example (and that's kind of the point!) the implications are huge. The ability to run and manage server processes is just one thing on a long list that makes Jaxer a good solution for ajax development. Simple, effective and best of all, it just works!

Resources

Following on

Next week I will take a look at the Jaxer.Request.data API which lets you get a handle to data sent to Jaxer via GET and POST operations. Be sure to subscribe to the CodeGobbler rss feed.

Uri's picture

Great example Tom. I just wanted to suggest a slight simplification. The runUptime() function can be collapsed to a single line:

return Jaxer.Process.exec("/usr/bin/uptime");

Many parts of Jaxer have a simple static (function-call-like) interface such as the above, as well as a more controllable object-oriented interface like what you originally used.

tom's picture

Excellent, it just gets easier and easier! I've updated the article but for the record, I originally went about it like this, which was clearly a little more long-winded than it really needed to be:

function runUptime() {
  var processExec = new Jaxer.Process('/usr/bin/uptime');
  processExec.stdout = String();
  processExec.exec();
  return processExec.stdout;
}

[...] certain form elements before they reach the client's browser. (If anybody read last weeks article 'Running server side processes via JavaScript with Jaxer' you may remember that I said I was going to look at the Jaxer.Request.data API this week. Well, I [...]

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.