Cloud Zone is brought to you in partnership with:

Jeremy Foster was educated in computer engineering and mathematics, gathered disparate industry experience in education, aerospace manufacturing, and insurance. With just enough and not nearly enough education and experience, he finally joined Microsoft with the goal of informing and inspiring other software developers to write code and write it right. When he is not working, he is likely spending time with his wife and son, hiking and camping, sailing, scuba diving, or working on house projects. Jeremy is a DZone MVB and is not an employee of DZone and has posted 14 posts at DZone. You can read more from them at their website. View Full User Profile

Anatomy of a Push Notification

11.16.2012
| 6765 views |
  • submit to reddit

I can hardly stand not knowing how something works under the hood. More often than not, I'd rather have a working knowledge of a system than the convenience or function of the system itself. It's why I chased degrees in Computer Electronics and Computer Engineering in the first place. I don't know so much about all of the fancy things that engineers put into processors and primary system boards these days, but I'm relieved to have at least a fundamental understanding of a control bus, a machine clock, a MOSFET, an assembly program, and the higher level software abstractions. But I digress…

What I want to talk about right now is the anatomy of a push notification message. I was intimidated by the subject when I was first introduced to it, but I've climbed on top of the general concept now and feel confident enough to post on the matter.

I do have to say that I'm pretty excited about the convenience of Windows Azure Mobile Services (WAMS) abstractions over the process, but I don't want to use it blindly without understanding what it's doing under the hood. I'm going to start with a review of the process and players in a typical push notification. You can find this diagram and an overview of the process here.

The green is you and the blue is Microsoft. You are writing an app and you are responsible for a cloud service to communicate with WNS.

In my typical attempt to make complex sound easy, I'm going to walk you through this process.

  • [Steps 1-3] Your apps asks Windows for a channel.

    You ask Windows for a channel, Windows asks WNS (this happens transparent to you), and then Windows gives you a channel. This channel is just a string. Here's a sample URI with an ellipse since it's actually much longer.

    https://bn1.notify.windows.com/?token=AgYAAABrcyAqFeh...wfOG5%2bD4TCeHU%3d

    By the way, the channel that Windows gives you also includes an expiration time which may be helpful.

  • [Step 4] Your app sends this URI to your cloud service

    You can use whatever means you choose, but I would hope that you'd find a smart and secure way to do that. A potential attacker would have to get this URI and also your Package Security Identifier and Client Secret in order to start sending malicious app notifications, but still.

  • [Step 5] Your cloud service asks WNS (Microsoft's server) for an access token and then triggers a push

    Here's where the bulk of the "magic" happens. Your service does two HTTP calls. The first gets it an access token (which you'll likely want to cache), and the second (and subsequent) initiate pushes to your app. WNS knows where your app is because of the URI that you sent it.

    Here are examples of those two raw HTTP messages…

    First message

    POST /accesstoken.srf HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Host: https://login.live.com
    Content-Length: 211
    grant_type=client_credentials&client_id=ms-app%3a%2f%2fS-1-15-2-2972962901-2322836549-3722629029-1345238579-3987825745-2155616079-650196962&client_secret=Vex8L9WOFZuj95euaLrvSH7XyoDhLJc7&scope=notify.windows.com

    It's just a simple POST to login.live.com/accesstoken.srf. The client_id is actually the Package Security Identifier (SID) that you get from your developer dashboard at http://dev.windows.com, and theclient_secret is the Client Secret that you find in the same place.

    The response to a successful access token request is something like…

    HTTP/1.1 200 OK 
    Cache-Control: no-store 
    Content-Length: 422 
    Content-Type: application/json
    { 
    "access_token":"EgAcAQMAAAAALYAAY/c+Huwi3Fv4Ck10UrKNmtxRO6Njk2MgA=",
    "token_type":"bearer" 
    } 

    With that, your service has what it needs to submit notifications to be pushed to your app.

    Second message

    Your service has the access token and that's all it needs to issue requests for WNS to push to your app.

    Here's a push message that changes the text on your tile…

    POST https://bn1.notify.windows.com/?token=AgYAAABrcyAqFeh...wfOG5%2bD4TCeHU%3d HTTP/1.1 
    Content-Type: text/xml 
    X-WNS-Type: wns/tile 
    Authorization: Bearer EgAcAQMAAAAALYAAY/c+Huwi3Fv4Ck10UrKNmtxRO6Njk2MgA= 
    Host: bn1.notify.windows.com 
    Content-Length: 32 
    
    <tile><visual><binding template="TileSquareText03"><text id="1">Message sent from push</text></binding></visual></tile>

    Notice a few things about this message…

    • Just like the request for an access token, this is a secure post to https
    • The message is sent to the channel URI
    • You can find valid values for the Content-Type and X-WNS-Type headers here
    • The Authorization header always has that word Bearer, a space, and then the access token received from the first call

  • [Step 6] WNS sends the notification to your app

    This step is all on WNS and Windows and you don't have to do anything except for verify that the process worked.

And there you have it. You can find numerous services that wrap this process for you and make it easy, but now you know the guts of what's going on under the hood. It's not exactly something you want to try to explain to your mom, but it's not exactly quantum physics either.

Published at DZone with permission of Jeremy Foster, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)