Remote debugging with jsconsole, a different take

Ever wanted to remotely access the DOM of a mobile device so you could make changes, test ideas and generally just have a bit of fun. I know I have and I’ve been hacking to create a proof of concept piggy backed on the development of two great projects. The first is Remy Sharps awesome little jsconsole web app that lets you do a bunch of cool stuff using a simple yet elegant interface. The second is a Firefox plugin that allows Firefox to act as a WebSocket server and receive and delegate messages sent from a client.

Remy recently added remote debug functionality by the way of an intermediate server to delegate commands, mine works differently and the two solutions could work well together.

In order to use the demo you’ll need to install the BrowserSocket add-on first.

For a quick intro on what you can do, watch the screencast below. I’ll go into how it works on a technical level in the rest of the article. I’ve also filmed a super dodgy looking video of the remote debugging on the iPad.

Browser to browser connections

As mentioned in the intro and screencast this requires the very clever, and awesome, BrowserSocket Firefox addon which allows you to let a browser window act as a WebSocket server that can be connected to by a client using the standard WebSocket API. The beauty of this is it requires very little setup and no actual server, browser to browser communication. In order to communicate with external devices they just need to be on the same local network as your current browser, you can even create an adhoc network between your computer and the device and remote debug that way.

Connecting the client to the console

There a two ways you can connect a client to the jsconsole webapp.

Using the client bookmarklet you can load it on any website and connect to the generated websocket address, make sure the client and the remote device are on the same network. Once an active connection is obtained any console calls will be sent to both the client and the jsconsole webapp, all JavaScript calls will be executed on the client including loading of js libraries.

The second is including the JavaScript file in your project the advantage of this is you can setup automatic connections so any console calls will be sent to the web app.


How it works on a technical level

Once you have installed the BrowserSocket addon in jsconsole you can call the :createServer command which will generate a WebSocket address that you will connect the client to.

createServer command opens a BrowserSocket instance and gives you a WeSocket address to connect to
:createServer command opens a BrowserSocket instance and gives you a WeSocket address to connect to

Behind the scenes the BrowserSocket addon exposes the BrowserSocket() constructor which uses the nsIServerSocket interface available to Firefox addons to create a socket server with the ability to accept incoming connections.

Using the constructor we create a new instance and supply a connection handler which will initialise the server instance and allow you to attach functions to the various events i.e. onopen/message/close etc same API as WebSockets.

var bs = new BrowserSocket(bsHandler),
     bsConnection;
 
function bsHandler() {
    return new function() {
        bsConnection = this;
        bsConnection.onmessage = function(msg) {
            // Handle messages sent to browsersocket
        }
        bsConnection.onopen = function() {
            // Run stuff once connection is open
        }
        bsConnection.onclose = function(e) {
            // Revert changes once connection is closed
        }
    }
}

On the client side we simply use the native WebSocket API to connect to our BrowserSocket instance upon successful connection it will log a success message to both client and jsconsole webapp. Very simple and very powerful.

var ws = new WebSocket(url);
 
ws.onmessage = function(msg) {
   // Eval code sent from jsconsole
}
ws.onopen = function() {
   // Run stuff once connection is open
}
ws.onclose = function(e) {
   // Revert changes once connection is closed
}

There is one more command called :killServer which does just that, kills the BrowserSocket instance and disconnects jsconsole from the client.

killServer command kills the BrowserSocket instance and if there is an active connection closes that too
:killServer command kills the BrowserSocket instance and if there is an active connection closes that too

bsConnection.close();
bs.stop();

It’s only the beginning

I have many ideas that I will be implementing such as a :cd command so you can switch between connected device and jsconsole web app. I’ll add a roadmap/ideas wiki on my github fork soon. If you wish to suggest a feature create an issue for now.

I have also created a fork of the BrowserSocket addon on github that will eventually have some minor updates to help with remote debugging such as returning your local ip to make it easier to connect to remote devices. You can check out the master repository on launchpad to follow the actual developments of the addon.

[link href=”http://cssn.in/ja/032″]