Minimal Android ZeroMQ Client/Server Example

Novoda has a reputation of building the most desirable apps for Android. We believe living and sharing a hack-and-tell culture is one way to maintain top-shelf quality.

While researching possible technologies for implementing a publish/subscribe-based task distribution system for long-running, semi-autonomous/intelligent agents (with Android as a supported platform), ZeroMQ emerged as a sensible choice of message transport, given the exploding complexity of AMQP (Pieter Hintjens' August 2008 steering committee missive sums up my misgivings).

ZeroMQ vs. JeroMQ

The ZeroMQ/jzmq Android build instructions look pretty onerous, particularly for pre-3.0 versions (due to a libuuid dependency)—JeroMQ (a pure Java implemention)—seemed like a natural choice. I haven't benchmarked anything like a real-world use case, though there are some promising numbers published by the JeroMQ authors.

Since the JeroMQ and jzmq (0.2.0 series) API structures are functionally identical, there shouldn't be any real cost associated with making a choice for exploratory reasons (barring showstopping bugs). The code snippets below adumbrate a minimal working example of a ZMQ client/server in request/response mode, running in a single process (an Android application). There are a dearth of Android-specific ZMQ examples around—I've endeavoured to use Android-specific concurrency abstractions where they seem idiomatic.

Note that the purpose of this example/tutorial is to provide examples of how to issue a request and process a response using a trivial message format with ZMQ—while all of the work is happening in a single process, the server & client threads can be viewed as separate applications; trivial adaptations of the Hello World request/response example applications (hwclient & hwserver) which are ubiquitous in ZMQ tutorials.

Code

Let's start with a Handler which takes an instance (conforming to a trivial interface) to which it dispatches message events, and a key name identifying the String datum within the corresponding Message's Bundle which holds the message payload.

Predictably, the interface isn't particularly jazzy.

The long-running server, which blocks on reads and instantly responds with a reversed version of the message payload is defined as a Runnable, taking a Handler which is used to communicate the content of incoming messages to interested parties.

The client/request-side is implemented as an AsyncTask which re-does all of its setup when run. AsyncTask.execute takes a String to use as the message body, and the constructor, as above, takes a Handler to which received messages are dispatched (after being bundled).

UI

Screenshot

The UI is incredibly simple, and the layout XML doesn't bear repeating. The three pieces of information required to make the Activity code intelligible are:

Wiring Everything Together

Notes:

Alternatives

MQTT makes sense on a couple of axes, though it may be a slightly curious choice given the heterogeneity of clients in this use-case (it'd be easier to defend if clients were exclusively Android, or mobile-only). It may well be the subject of a follow-up blog-post.

ZeroMQ is used more in the wild, and it may be more flexible in case any strange requirements emerge (for example, if we were to develop an in-browser Javascript task consumer which required the proxying of ZMQ messages over HTTP, then the existence of middleware-factories like Mule might make this easier). There's an example of what looks something like ZMQ over HTTP via Mule although I haven't looked at it (Mule, nor that example) in depth. The word “middleware” makes me a little queasy.

About Novoda

We plan, design, and develop the world’s most desirable Android products. Our team’s expertise helps brands like Sony, Motorola, Tesco, Channel4, BBC, and News Corp build fully customized Android devices or simply make their mobile experiences the best on the market. Since 2008, our full in-house teams work from London, Liverpool, Berlin, Barcelona, and NYC.

Let’s get in contact