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.
<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
- The Jaxer project homepage
- Download Aptana Jaxer
- Understanding the Jaxer architecture
- Jaxer Framework API
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.






20th Aug 2008, 12:36am
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.
20th Aug 2008, 12:00am
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:
25th Aug 2008, 10:09am
Post new comment