Sunday, 22 September 2013

GSoC - Push Notify test examples.

To show a simple usage of push notifications I developed 2 test examples.
I really want to thank FPComplete for giving me the possibility of hosting the Yesod app.
The tests are available online on [1] and the code is available on GitHub [3].

* BackAndForth Messaging:
In this example, I show how to use the push-general library to handle the registration/reception and sending of messages. From a Yesod app, you can send notifications to devices registered and receive messages from them.
When the server needs to send a message, uses the general api for sending a notification and handling the result in order to correctly actualize the DB. This means removing the devices that have been unregistered and changing the regId of the devices that have changed.
To try this example:
+ On an Android device, you follow these steps: [2].
+ On a WindowsPhone device, you can download the app from Microsoft Store: [4]
+ Once you registered on Server, you can start sending/receiving notifications through the website: [1].

* Connect 4:
I have been thinking of an app which lets me show how useful push notifications are. The advantage of this notifications is that you can receive information from server when it is available without needing to continually poll. So, I started to think about a multiplayers game. Every time a player does something, you let the rest know about the new movement. So, I ran into the board game: "Connect 4".
Both, authenticated web players and users of the android app, can play one against each other.
For actualizing the website, I use long polling, while for the Android app, push notifications.

Main modules description:
 - CommDevices : defines the main callback functions to communicate with mobile devices using the general library.
 - CommWebUsers : defines the main functions to handle the set of Web users.
 - Connect4 : defines the main functions to save the state of the Connect4 game.
 - DataBase : defines the DB structure.
 - Handlers :  defines the main function to handle the messages that comes from users (web or Android users).
 - Main : defines the Yesod app.

To try the example:
+ On an Android device, you follow these steps: [2].
+ Once you registered on Server, you can start playing against web or Android users. [1]

Every feedback is welcome!


3 Libraries for communicating with Mobile devices through Push Notifications.

I announce the result of 3 months working on the GSoC project: "Communicating with mobile devices". After reading many documentation, thinking about a good abstraction, learning about mobile apps and networks connections, and really valuable recommendations from my mentor, (I really want to thank Michael Snoyman for his availability and kindness) I finished developing 3 libraries to make it easy to send push notifications to mobile devices. They are available on Hackage:

* push-notify- : This library offers a simple API for sending notifications through APNS, GCM and MPNS. [1]

* push-notify-ccs- : This library offers an API for sending/receiving notifications through CCS (XMPP - Google Cloud Messaging). [2]

* push-notify-general- : This library offers a general API for sending/receiving notifications, and handling the registration of devices on the server. It provides a general abstraction which can be used to communicate through different services as APNS, GCM, MPNS, hiding as much as possible, the differences between them. [3]

Now, it is easy to send/receive information with mobile devices, so you can easily develop server applications which interact with them.
So, to clarify this, as part of this project, I developed many test examples, including Android/WPhone and Yesod apps. The code is available on GitHub: [4] and they are running online on: [5] , so can be downloaded and tested on mobile devices. (BackAndForth Messaging and Connect4 apps)
Every feedback is welcome!


Saturday, 21 September 2013

push-notify-general: A general library for sending Push Notifications.

The purpose of this library

This library defines a general API for communicating with iOS, Android and WPhone powered devices, sending/receiving Push Notifications. It is available on Hackage: link
The main idea is to hide as much as possible the differences between the different services.
Push Notification services in general, are very similar. They all are asynchronous, best-effort services that offer third-party developers a channel to send data to apps from a cloud service in a power-efficient manner. The main differences between them, refer to details as: the maxim payload length, the quality of service, queueing the messages or not, and the time limit for this, the way the messages are handled on devices, etc.
The registration of devices is very similar too. The device/app gets a unique ID provided by the different services, and sends this identifier to your 3rd party server. So then, when you want to send messages to these devices, you have to send them to the Push Servers, and they will deliver the messages to the proper devices.
So, Device will be our general identifier.

How to use this library

All the communication with devices will be abstracted behind the PushManager data type.
You will reference to it when intending to send notifications. Also, if you properly set the callback functions, you will be able to receive messages from devices.
So, the mains steps:
  • First you establish the main configuration for the push service: PushServiceConfig . This means, set the configurations for the different Push services you want to use, and also set the callbacks functions. These functions could be used to actualize a DB, do some processing in background, etc.
  • Then you start the service with the startPushService function and you get the PushManager. So, you can add this subsite to your Yesod app or just ignore it if you don't want to receive messages from devices.
  • When you want to send notifications:
  1. You have to specify the PushNotification , setting the parameters. Here you have to do it for each kind of notification, because they contain different structures.
  2. Then, you can send these with the sendPush function, passing the PushManager as an argument. Also, you can get useful information from the PushResult value after communicating with servers.
When your Apps on devices need to send an upstream message they have 2 options:
  1. Messages through CCS (only Android devices). For this you have to set the proper CCS settings when starting the Push Service.
  2. Messages as HTTP requests to PushManager Yesod subsite (all devices). (using the route of the Yesod subsite: something like ".../messages" )
You can see many test examples on the GitHub repository:

PushManager Subsite

Everytime a device sends a message to our system as HTTP POST request it should provide the pair {"regId" : identifier , "system" : system } specifing the ID and the system running on the device, so we can build the Device identifier.
Now we support APNS, MPNS and GCM. So the possible combinations are:
{ "regId" : RegId , "system" : "ANDROID" }
{ "regId" : DeviceURI , "system" : "WPHONE" }
{ "regId" : DeviceToken , "system" : "IOS" } (token stored in hexadecimal representation)
This PushManager Yesod subsite consists of 2 routes for receiving JSON data:
  • /register -> this route will receive the registration from devices. So devices have to send the pairs {"regId" : identifier , "system" : system } and any extra information. When a new intent for a registration arrives, the newDeviceCallback function will be called with the identifier and JSON data as arguments so you can ask for more information as username and password, etc. Depending on the callback function result, the response to the POST request will be set, so device can know if it has successfully registered on the server.
  • /messages -> this route will receive POST messages from devices. Again, devices have to send the pairs {"regId" : identifier , "system" : system } and any other extra information. Everytime a new messages arrives to the Yesod subsite, the newMessageCallback function will be called with the identifier and JSON data as arguments. This abstraction lets us use the same callback function to handle the messages that arrive from CCS too (XMPP connection for GCM).