So far I’ve only talked about the idea / conceptof the Akka-Mobile. This time I show some small code examples =). Of course the current implementation is a uncompleted prototype. The implementation itself throws not implemented exceptions around every corner or has other unknown behavior. The API is nowhere near completion or final stage. Anyhow I just want show how it ‘feels’ like and throw in a few comments. Also keep in mind that Akka 2.0 is not that far away, and I will almost certainly move to it sooner or later.
First let’s start a server. This is easily done by calling NettyRemoteServer.start() which starts up the server and listens to the specified port. Don’t confuse this with the regular Akka 1.2 remote actors. The mobile actors will use their own server-implementation. That’s also quite intentional: We want to expose only certain ‘service’ actors to our mobile clients and keep the rest internal to our cluster / internal infrastructure.
After that we can register regular actor to the given server instance. These actors then are reachable by the mobile clients under the given id. For example a ultra simple actor which just echoes the request:
Well that’s not very exiting. It’s nearly identical to the regular Akka 1.2 remote actor.
On The Android Device
Now let’s move on to the Android device. The first thing we need to do is to get Scala running =). Then we start with a normal ‘main’ activity. Optionally we can use the trait ‘ActivityActor’ which turns our activity into an actor. Any message send to the activity will be dispatched on the ‘activity’ thread, so that we can update the UI etc. Like this:
For remote actors we need a client instance, usually one per application. When creating such an instance we need to pass in a Android context, which allows the remote implementation to get to Android resources. The other arguments are optional or loaded from the configuration. I’ve put my remote instance in the global application object which is then registered in the Android manifest.
In the akka.conf we specify the host, port and preferably the Logcat logger:
After that we can get references to actors on the server by name and send messages to them. So we now can communicate with the actors on the server. Nice =)
So far so good, we’ve connected from the Android device to the server, got a reference to it and started communicating with it.
But what if the server wants to initiate the communication with a client? To do that we register an actor on our remote instace! The server will later be able to contact this client-actor by its name:
The first thing we need is an ‘address’ for a client. Since mobile devices are on the move, they don’t permanent IP address. Akka mobile provides a ‘clientId’ as a replacement. You can get that id in multiple way. For example when a server-side actor is communicatong with a Android device the self-reference will contain this client id. With the trait ServiceActor you get a nice accessor:
As soon as we have a client id we can get an reference for an actor running on the device and start sending messages to it.
But Wait, What if the Device is Offline?
Now the stuff I’ve showed so far only works as long as the Phone has a connection to the Server. What if the Phone is offline? Or the application isn’t running. Well here’s where the C2MD integration comes in. Akka mobile can deliver messages via C2MD. Here’s a short overview how it works.
Preparation on the Server
First we need to configure the Server to support C2MD: We need to add two things: The C2MD authentication key for talking to the C2MD servers and a database backend. The database backend is required to store the registration ids of all devices.
So in the akka.conf configuration we add:
And we start the server with a given database :
Preparation on the Client
On the client we also update the akka.conf. We add the email for which the C2MD service is registered:
Additionally we need a broad cast receiver which handles the C2MD intents. We inherit the ‘C2MDReceiver’ -trait and implement the ‘remoteClient’ method. In that method we return our instance of the akka-mobile remote client which our application is using. In this example I’ve that instance in the application object and get it from there (via ugly cast, don’t hit me).
In the Android Manifest you need to get the permissions for C2MD and register the broadcast receiver previously created:
After that akka mobile is ready to use C2MD. It will register the application automatically and report its registration-id to out server as soon as the remote-instance is created. Or you can optionally disable the auto-registration and use ‘requestC2MDRegistration()’ to start the C2MD registration at a certain point in time.
Sending a Message over C2MD
Now messages are still not sent with C2MD if no connection is available. The reason is that akka-mobile wants to prevent that we send hundreds of messages via C2MD by accident. We should be very careful and only sent important notifications over C2MD. There are two ways to achieve that.
One is to use the marker-trait ’SentThroughC2MDIfNoConnectionIsAvailable’ in your message. If a message implements this trait it will be delivered via C2MD if no connection is found.
The other possibility is by using a ‘error’-handler which falls back on C2MD if no connection can be established. However I explain error-handlers next time, since they are quite central to the whole communication stack.
Stuff Still To Implement for a Proper Prototype
So, that the first look at how akka-mobile will work. There still tons of things to do. Also very basic stuff:
- Improve stability, test-suite and build-process.
- Better integration with Android, especially the connection-manager. Maybe also with power management.
- ‘Session’ actors on the server
- Better serialization story. Currently only Java Serialization is supported. Java serialization always makes me nervous.
- Error-Handler API has to improve, a lot. More about that next time.
- Do some basic performance analysis.
- Finally start on ‘cool’ features….
Otherwise I’ve tons of other features I want to tackle, but those above are really needed to get to a more stable state.
Conclusion and Next Time
So we’ve seen how we can setup the akka mobile remote actors. It allows us to have nice device to server communication between actors. It also allows us to fall back on C2MD messages when a client doesn’t have a connection to a server.
Next time I’m going to talk about error-handlers. These are responsible for managing connection loses etc.
- TV-Series Reviews and Stuff?
- Doctor Who Second Half of Series 6 *Spoilers*