I am using Azure notification hub to send push notifications from Raspberry pi to android application.
I am using python client app using REST API as per this post How to use Notification Hubs from Python
Everything works fine but there is, almost 2 seconds of delay in every notification from Raspberry pi to Android application!! How to avoid this delay and get the notification on Android device within same second.
My python script
import time
import hmac
import base64
import hashlib
import json
import urllib.parse
import http.client
class Notification:
    def __init__(self, notification_format=None, payload=None, debug=0):
        valid_formats = ['template', 'apple', 'gcm', 'windows', 'windowsphone', "adm", "baidu"]
        if not any(x in notification_format for x in valid_formats):
            raise Exception(
                "Invalid Notification format. " +
                "Must be one of the following - 'template', 'apple', 'gcm', 'windows', 'windowsphone', 'adm', 'baidu'")
        self.format = notification_format
        self.payload = payload
        # array with keynames for headers
        # Note: Some headers are mandatory: Windows: X-WNS-Type, WindowsPhone: X-NotificationType
        # Note: For Apple you can set Expiry with header: ServiceBusNotification-ApnsExpiry
        # in W3C DTF, YYYY-MM-DDThh:mmTZD (for example, 1997-07-16T19:20+01:00).
        self.headers = None
class NotificationHub:
    API_VERSION = "?api-version=2013-10"
    DEBUG_SEND = "&test"
    def __init__(self, connection_string=None, hub_name=None, debug=0):
        self.HubName = hub_name
        self.Debug = debug
        # Parse connection string
        parts = connection_string.split(';')
        if len(parts) != 3:
            raise Exception("Invalid ConnectionString.")
        for part in parts:
            if part.startswith('Endpoint'):
                self.Endpoint = 'https' + part[11:]
            if part.startswith('SharedAccessKeyName'):
                self.SasKeyName = part[20:]
            if part.startswith('SharedAccessKey'):
                self.SasKeyValue = part[16:]
    @staticmethod
    def get_expiry():
        # By default returns an expiration of 5 minutes (=300 seconds) from now
        return int(round(time.time() + 300))
    @staticmethod
    def encode_base64(data):
        return base64.b64encode(data)
    def sign_string(self, to_sign):
        key = self.SasKeyValue.encode('utf-8')
        to_sign = to_sign.encode('utf-8')
        signed_hmac_sha256 = hmac.HMAC(key, to_sign, hashlib.sha256)
        digest = signed_hmac_sha256.digest()
        encoded_digest = self.encode_base64(digest)
        return encoded_digest
    def generate_sas_token(self):
        target_uri = self.Endpoint + self.HubName
        my_uri = urllib.parse.quote(target_uri, '').lower()
        expiry = str(self.get_expiry())
        to_sign = my_uri + '\n' + expiry
        signature = urllib.parse.quote(self.sign_string(to_sign))
        auth_format = 'SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}'
        sas_token = auth_format.format(signature, expiry, self.SasKeyName, my_uri)
        return sas_token
    def make_http_request(self, url, payload, headers):
        parsed_url = urllib.parse.urlparse(url)
        connection = http.client.HTTPSConnection(parsed_url.hostname, parsed_url.port)
        if self.Debug > 0:
            connection.set_debuglevel(self.Debug)
            # adding this querystring parameter gets detailed information about the PNS send notification outcome
            url += self.DEBUG_SEND
            print("--- REQUEST ---")
            print("URI: " + url)
            print("Headers: " + json.dumps(headers, sort_keys=True, indent=4, separators=(' ', ': ')))
            print("--- END REQUEST ---\n")
        connection.request('POST', url, payload, headers)
        response = connection.getresponse()
        if self.Debug > 0:
            # print out detailed response information for debugging purpose
            print("\n\n--- RESPONSE ---")
            print(str(response.status) + " " + response.reason)
            print(response.msg)
            print(response.read())
            print("--- END RESPONSE ---")
        elif response.status != 201:
            # Successful outcome of send message is HTTP 201 - Created
            raise Exception(
                "Error sending notification. Received HTTP code " + str(response.status) + " " + response.reason)
        connection.close()
    def send_notification(self, notification, tag_or_tag_expression=None):
        url = self.Endpoint + self.HubName + '/messages' + self.API_VERSION
        json_platforms = ['template', 'apple', 'gcm', 'adm', 'baidu']
        if any(x in notification.format for x in json_platforms):
            content_type = "application/json"
            payload_to_send = json.dumps(notification.payload)
        else:
            content_type = "application/xml"
            payload_to_send = notification.payload
        headers = {
            'Content-type': content_type,
            'Authorization': self.generate_sas_token(),
            'ServiceBusNotification-Format': notification.format
        }
        if isinstance(tag_or_tag_expression, set):
            tag_list = ' || '.join(tag_or_tag_expression)
        else:
            tag_list = tag_or_tag_expression
        # add the tags/tag expressions to the headers collection
        if tag_list != "":
            headers.update({'ServiceBusNotification-Tags': tag_list})
        # add any custom headers to the headers collection that the user may have added
        if notification.headers is not None:
            headers.update(notification.headers)
        self.make_http_request(url, payload_to_send, headers)
    def send_apple_notification(self, payload, tags=""):
        nh = Notification("apple", payload)
        self.send_notification(nh, tags)
    def send_gcm_notification(self, payload, tags=""):
        nh = Notification("gcm", payload)
        self.send_notification(nh, tags)
    def send_adm_notification(self, payload, tags=""):
        nh = Notification("adm", payload)
        self.send_notification(nh, tags)
    def send_baidu_notification(self, payload, tags=""):
        nh = Notification("baidu", payload)
        self.send_notification(nh, tags)
    def send_mpns_notification(self, payload, tags=""):
        nh = Notification("windowsphone", payload)
        if "<wp:Toast>" in payload:
            nh.headers = {'X-WindowsPhone-Target': 'toast', 'X-NotificationClass': '2'}
        elif "<wp:Tile>" in payload:
            nh.headers = {'X-WindowsPhone-Target': 'tile', 'X-NotificationClass': '1'}
        self.send_notification(nh, tags)
    def send_windows_notification(self, payload, tags=""):
        nh = Notification("windows", payload)
        if "<toast>" in payload:
            nh.headers = {'X-WNS-Type': 'wns/toast'}
        elif "<tile>" in payload:
            nh.headers = {'X-WNS-Type': 'wns/tile'}
        elif "<badge>" in payload:
            nh.headers = {'X-WNS-Type': 'wns/badge'}
        self.send_notification(nh, tags)
    def send_template_notification(self, properties, tags=""):
        nh = Notification("template", properties)
        self.send_notification(nh, tags)
isDebug = True
myConnectionString =  "connection string"
hub = NotificationHub(myConnectionString, "cavenotificationhub", isDebug)
data = {}
data['response'] = 'data: R1|X1|S1,1|$'
json_data = json.dumps(data,separators=(',',':'))
print(json_data)
#gcm_payload = {"response":R1|X1|S1,1}
val= "R1|X1|S1,1|$"
gcm_payload = { 'data' : {'response': ''+val+''}}
hub.send_gcm_notification(gcm_payload)
Attached logs:
Windows 10 Surface Pro 3 - Python 3.4 script
**** Send GCM Notitification START>  2016-05-08 10:42:07.883226
*** make_http_request connection OPEN>  2016-05-08 10:42:08.139328
--- REQUEST ---
#Request header
--- END REQUEST ---
*** make_http_request START>  2016-05-08 10:42:08.165356
#Sending request to Azure
*** make_http_request END>  2016-05-08 10:42:09.016024
--- RESPONSE ---
#Response received from Azure
--- END RESPONSE ---
*** make_http_request connection CLOSE>  2016-05-08 10:42:09.184785
**** Send GCM Notitification END>  2016-05-08 10:42:09.188788
################################################################################################################################ Raspberry Pi Model B+ V1.2 - Python 2.7 script
('*** Send GCM Notitification START> ', '2016-05-08 10:46:32.692844') ('*** make_http_request connection OPEN> ', '2016-05-08 10:46:32.698456')
--- REQUEST ---
#Request header
--- END REQUEST ---
('*** make_http_request START> ', '2016-05-08 10:46:32.705946')
#Sending request to Azure ('*** make_http_request END> ', '2016-05-08 10:46:39.557759')
--- RESPONSE ---
#Response received from Azure
--- END RESPONSE ---
('*** make_http_request connection CLOSE> ', '2016-05-08 10:46:39.569713') ('*** Send GCM Notitification END> ', '2016-05-08 10:46:39.570986')
################################################################################################################################ Raspberry Pi 2 Model B V1.1 - Python 2.7 script
('*** Send GCM Notitification START> ', '2016-05-08 05:36:49.721024') ('*** make_http_request connection OPEN> ', '2016-05-08 05:36:49.732056')
--- REQUEST ---
#Request header
--- END REQUEST ---
('*** make_http_request START> ', '2016-05-08 05:36:49.733069')
#Sending request to Azure ('*** make_http_request END> ', '2016-05-08 05:36:50.741605')
--- RESPONSE ---
#Response received from Azure
--- END RESPONSE ---
('*** make_http_request connection CLOSE> ', '2016-05-08 05:36:50.746248') ('*** Send GCM Notitification END> ', '2016-05-08 05:36:50.747000')