Excursion — WebSocket on Android

Feb 2013

It’s been a long time since I made any web development on mobile, and I have never tried out WebSocket, so let’s see how feasible it is to create an Android WebSocket server and interface it with an Android HTML client.

Step 1) set up a WebSocket server on desktop

There are a lot of full featured WebSocket servers out there. I want something simple to test the water. web-socket-ruby seems to fit the bill.

Cloning the repo and starting an echo server is easy enough.

➤ git clone https://github.com/gimite/web-socket-ruby.git
➤ cd web-socket-ruby
➤ ruby samples/echo_server.rb localhost 10081

Step 2) try a WebSocket client on desktop

WebSocket.org has a simple echo client. It works against the default ws://echo.websocket.org/ URI. Changing wsUri to ws://localhost:10081/ causes the server to barf some errors.

web-socket-ruby/lib/web_socket.rb:63:in `initialize': Unaccepted origin: null (server.accepted_domains = ["localhost"])

That’s probably due to the web page being opened with file:// instead of being served by a server. Least resistance: comment out the origin checks in web-socket-ruby/lib/web-socket.rb. Now it works :-)

Step 3) try the client on Chrome on Android

According to Can I use WebSockets? my browser choices on Android are Chrome for Android, Opera Mobile and Firefox for Android. Chrome is my browser of choice.

Changing wsUri once more to match the IP of my laptop, I upload the HTML file to my phone and open it in Chrome for Android.

Well look at that.

Screen shot of echo client working on Chrome for Android

The origin issue is consistent with desktop Chrome, server says:

Connection accepted
Path: /, Origin: null
Received: "WebSocket rocks"
Sent: "WebSocket rocks"
Connection closed

As expected it doesn’t work on the Android Browser. But it works equally well on Firefox for Android, Chrome, Chrome Beta and Opera Mobile.

Step 4) try out remote debugging for Chrome

So the work flow of uploading files to the phone is not feasible and there are a number of alternatives, but I’ve always wanted to try remote debugging for Chrome.

It’s very well documented over here.

Well, it’s extremely easy. After the initial settings, launching it is just a few commands away:

➤ adb forward tcp:9222 localabstract:chrome_devtools_remote
➤ open http://localhost:9222

Step 5) get a WebSocket server running on the phone

Java-WebSocket looks like a good implementation that is known to work on Android. It compiles without a hitch.

Least resistance: start a WebSocket server in an Activity’s onCreate().

// Initialize and start echo server
final int port = 8080;
WebSocketImpl.DEBUG = true;
WebSocketServer server = new WebSocketServer(
        new InetSocketAddress(port)) {
    @Override
    public void onClose(WebSocket conn, int code, String reason,
            boolean remote) {
        Log.d("SERVER", "onClose()");
    }

    @Override
    public void onError(WebSocket conn, Exception ex) {
        Log.d("SERVER", "onError()", ex);
    }

    @Override
    public void onMessage(WebSocket conn, String message) {
        Log.d("SERVER", String.format("onMessage(%s)", message));
        conn.send(message);
    }

    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {
        Log.d("SERVER", "onOpen()");
    }
};

server.start();

This will start an echo server in a background thread. It’s not proper, one main issue is that it never stops the server. We should honor the Android activity life cycle, but it’ll work for now. Also we have to remember to add android.permission.INTERNET to AndroidManifest.xml.

With this we can modify wsUri of the HTML client to ws://localhost:8080/ (I did it using remote debugging and ran testWebSocket()). Everything seems to work.

Fin

That concludes today’s excursion. It seems very feasible to write a WebSocket server on Android and connect to it using a HTML page running in a browser on the same phone. There are some compatibility concerns with the built in Browser but for people who can’t run Chrome (it requires Android 4.0+), Firefox and Opera Mobile are available.