Mobile Push Notification Service – Design Approach (Part 1)

A high level design of Mobile push notification service.

Advertisements
Overview of Push Notifications

In this article, I am going to design the architecture for implementing push notifications for you mobile application. This part only has design and architecture information, code will be covered in Part 2.

If you are new to push notifications, please read wiki article about the technology and also about GCM and APN services.

Below diagram depicts a high level overview of device registration process.

DeviceReg

  1. Device sends sender ID, application ID to GCM server for registration.
  2. Upon registration Cloud Service (GCM/APNs) sends a unique registration ID to the device.
  3. After receiving the registration ID from the cloud service the device will forward the registration ID to the Push Notification Web Service.
  4. The Push Notification web service will store the registration ID in a local database for later use.

a. Whenever Push Notification service needs to send the notification, it has to call GCM/APN service with registration ID of the device which is stored in the database.

b. GCM/APN service will deliver the notification to respective mobile device based on the registration ID.

Push Notification service would require an outbound internet connection to send messages to cloud services. Make sure to open two outbound ports on your push notification server.

Push Notification Components

You would need to implement two components:

  1. Push Notification Web Service

Push notification web service could be a rest service. Bare minimum the web service should have two functionalities. One, to register new device and Second, to unregister a device.

  1. Push Notification Windows Service.

You need to implement a windows service which could spawn multiple threads to listen to a messaging queue at a specified address. This service should be capable to pick up messages as and when it arrives to the messaging queue. The service will then query the local database and get a list of eligible devices which should receive the notification message and communicate with the cloud messaging services to get the notifications delivered.

Push Notification Windows service is a Microsoft Windows® terminology. On non-windows platform this windows service will be a process which will be initiated with a start-up batch file which could be hooked up with tomcat initialization process.

Push Notification Architecture

Diagram below depicts the push notification architecture at high level.

HLD

  1. As depicted in the diagram above, the first step is get the unique device ID from the cloud messaging service. The mobile application should make a call to the cloud messaging service every time it is launched. It is important to make this call every time as it may so happen that the unique device ID assigned earlier has now expired.
  2. Second step is to call the Push Notification web service from the mobile application and include the unique device ID (received from cloud messaging service) in the payload. You may want to pass some additional information like the device type, device operating system etc in the payload. A sample payload JSON is shown below:

    DevicePayload:{
    
    deviceId:'APA9sdsdA',
    
    deviceType:'mobile/tablet',
    
    deviceOS:'android/apple',
    
    userID:'xyz@gmail.com',
    
    }
    
    
  3. Push notification web service will persist the payload in a local database.
  4. Core product which is responsible for generating events per user will create notification messages and publish it to the Messaging Queue.
  5. Push notification windows service’s functionality is to constantly poll the Messaging Queue and pull any new message that arrives to the queue. The service should then query the local database to get the device id associated with the user id for which the notification was generated.
  6. With the fetched device id, the windows service will then communicate with cloud messaging services (GCM/APN).

This is the architecture at high level to design push notification service for your mobile application. In the next article (Part-2), I will cover the code required to communicate with the cloud messaging services.

A Thread Safe Singleton Class in .NET

In this post I will demonstrate creating a singleton class in .Net that is thread safe. As usual the singleton class should have a private constructor as shown below so that any other class cannot “directly” create an instance of our singleton class.

Apart from that, I have created two global variables, one to hold the instance of the Singleton class and another one of type object which will be used later for synchronization between threads (more on that later).

    static SingletonSample _instance;
    static readonly object _synchronizer = new object();
    /// <summary>
    /// Private C'tor, so that this class cannot be instantited by other classes directly
    /// </summary>
    private SingletonSample()
    {

    }

Method 1 – Using synchronization lock

 

GetInstance is a public static method, this method is the only way by which any other class can get instance of the singleton class.

Below code snippet uses double check pattern before creating the instance of the singleton class. The first If statement, if true, will give the instance of Singleton class instantly. However, if _instance variable is null then program will enter a critical section (the lock statement) synchronized using a global object (_synchronizer). Inside the critical section, I am checking the _instance  variable again if it is null (double check), if it is, then we finally create the instance of the class.

One interesting point to note here is, I am not creating the instance directly and returning it back. I am first assigning the class reference into a temporary object of type SingletonClass (tempInstance) and then doing a  Volatile write on the actual instance variable (_instance).

 

 

        /// <summary>
        /// Method is responsible for providing instance of this class.
        /// </summary>
        /// <returns>Instance of SingleTonSample class</returns>
        public static SingletonSample GetInstance()
        {
            //If instance is available return that.
            if (_instance != null)
                return _instance;

            //Critical section. Ony one thread can enter at a time.
            lock(_synchronizer)
            {
                //Check again if the instance in null
                if(_instance == null)
                {
                    SingletonSample tempInstance = new SingletonSample();
                    //Volatile write to make sure that _instance is 
                    //populated with tempInstance reference without any compiler optimization.
                    Volatile.Write(ref _instance, tempInstance);
                }
            }

            return _instance;
        }

The problem with this approach is that if this method is used in a highly parallel system, the critical section will cause all threads to do nothing but wait for an instance of Singleton class to be created. However, this will happen only once when the first instance is getting created, but still, this is wasteful of the resources.

Below is another, more efficient way of creating a singleton which neither uses double check pattern nor it has a critical section for thread synchronization.

Method 2 – Without Critical Section or Double Check

Below method will allow multiple threads to create instance of Singleton class, but Interlocked class’s CompareExchange will make sure that only one instance is assigned to _instance variable. Objects created by other  threads and not assigned to _instance variable will soon become Orphan and  will be garbage collected at a later point of time by the CLR.

        /// <summary>
        /// Method is responsible for providing instance of this class without critical section
        /// or double check pattern.
        /// </summary>
        /// <returns>Instance of SingletonSample class</returns>
        public static SingletonSample GetInstance()
        {
            //If instance is available return that.
            if (_instance != null)
                return _instance;
            
            SingletonSample tempInstance = new SingletonSample();
            /*Multiple threads will create singleton object, but only 
            *one will be asssgined to _instance variable. Rest others will be 
            *GC'd (Garbage Collected) later at some point of time. 
            */
            Interlocked.CompareExchange(ref _instance, tempInstance,null);
            
            return _instance;
        }

Both methods are thread safe. However, method 2 is marginally more efficient and lean as compared to the first one.