WebAPI/SimplePush: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
Line 6: Line 6:
};
};


interface PushNotification : EventTarget {
interface PushNotification {


   // registers to receive push notifications for a given topic
   // registers to receive push notifications for a given topic
Line 23: Line 23:
   // this is the URL to which push notifications from the web application
   // this is the URL to which push notifications from the web application
   // must be sent to.
   // must be sent to.
   // application should send this and pushRequestID as a pair to the
   // application should send this to the application server
  // application server
   DOMString pushEndpoint;
   DOMString pushEndpoint;


   // this is the push request id that must be sent to the push server with
   // undefined when obtained from register().onsuccess.
   // every push notification update
   // contains version when obtained from PushEvent
   DOMString channelID;
   DOMString version;
};
};


interface PushEvent : Event {
interface PushEvent : Event {
   // this is topic string used when registering for push notifications
   PushRegistration target;
  DOMString channelID;
 
  // this is the most current version
  unsigned long long version;
}
}


Line 49: Line 44:
{
{
   ...
   ...
  "permissions": {
    ...
    "push": {
      "description": "Check for new mail"
    }
  },
   "messages": [
   "messages": [
     {"notification": "/view_to_launch.html"}
     {"push": "/view_to_launch.html"}
     {"notification-register": "/view_to_launch.html"}
     {"push-register": "/view_to_launch.html"}
   ]
   ]
}
}
Line 65: Line 54:
=== JavaScript ===
=== JavaScript ===
<pre>
<pre>
var emailEndpoint, imEndpoint;


// all notifications will be sent to the system message handler.
// all notifications will be sent to the system message handler.
Line 77: Line 68:
     // to register to listen for a notification,
     // to register to listen for a notification,
     // you simply call push.register
     // you simply call push.register
     navigator.pushNotifications.register();
     var reqEmail = navigator.pushNotifications.register();
    reqEmail.onsuccess = function(e) {
      emailEndpoint = e.result.pushEndpoint;
      storeOnAppServer("email", emailEndpoint);
    }
 
    var reqIm = navigator.pushNotifications.register();
    reqIm.onsuccess = function(e) {
      imEndpoint = e.result.pushEndpoint;
      storeOnAppServer("im", imEndpoint);
    }
   }
   }
});
});
Line 83: Line 84:
navigator.mozSetMessageHandler('push', {
navigator.mozSetMessageHandler('push', {
   handleMessage: function(e) {
   handleMessage: function(e) {
     e.channelID == This is the topic that is being observed
     e.target.pushEndpoint == This is the topic that is being observed
     e.version == This is the current version for this topic
     e.target.version == This is the current version for this topic
   }
   }
});
});
Line 91: Line 92:
// to unregister, you simply call..
// to unregister, you simply call..


navigator.pushNotifications.unregister(channelID);
AppFramework.addEventListener('logout', function() {
  navigator.pushNotifications.unregister(emailEndpoint);
  navigator.pushNotifications.unregister(imEndpoint);
});
</pre>
</pre>
=== Notes ===
The current spec works for apps. Ideally it should work for web pages loaded in browsers as well.
Current issues blocking this:
* mozSetMessageHandler indexes by app manifest. Web pages don't have app manifests.
* The lifetime of registrations for web pages needs specification.
* Every instance of a web page should be treated differently. So the same URL in two tabs should have different channels (and ask permission?). Again geolocation, desktop-notification and others may provide clues)
* In the case of the b2g browser, the browser is an app and so mozSetMessageHandler gets its manifest, and not access to the pages. We might want to bypass the browser and plug directly into the mozbrowseriframe of each tab. Again within each tab, user might navigate away from page, which may need invalidation.
=== UI ===
* During app installation, the user agent should notify the user that the app uses push notifications, and possibly deny permission.
* Web pages using push notification should show a doorhangar notification in the same way (look at geolocation to see how this is done).


== Server API ==
== Server API ==
Line 113: Line 130:


;ChannelID
;ChannelID
:Globally Unique identifier for a Channel
:Unique identifier for a Channel. Generated by UserAgent for a particular application.
 
;Endpoint
:Unique URL comprising the ChannelID. Generated by PushServer and sent to application.


UserAgent and AppServer will use a RESTful API to interact with the Push Server.
UserAgent and AppServer will use a RESTful API to interact with the Push Server.
Line 125: Line 145:
** <tt>digest</tt> = SHA1(tt)
** <tt>digest</tt> = SHA1(tt)
'''NOTE:''' Digest inconsistency will occur during /register and /unregister. This should NOT be considered as a state mismatch.
'''NOTE:''' Digest inconsistency will occur during /register and /unregister. This should NOT be considered as a state mismatch.
* UserAgent requests may include a /{network} prefix to indicate a request may be handled by a third party network (e.g. <code>GET http:<i>host</i>/foonet/update</code> will return update requests for elements provided by the "foonet" sub-provider.
* UserAgent requests may include a /{network} prefix to indicate a request may be handled by a third party network (e.g. <code>GET http:<i>host</i>/foonet/update</code> will return update requests for elements provided by the "foonet" sub-provider. '''TODO: The semantics of this are woefully lacking in the current state of the protocol'''
* Calls will return standard HTTP status headers.  
* Calls will return standard HTTP status headers.  
* Calls will return status 200 (unless otherwise noted below).
* Calls will return status 200 (unless otherwise noted below).
Line 131: Line 151:


==== GET /v1/register/<channelID> ====
==== GET /v1/register/<channelID> ====
Request a new ChannelID.  
Request a new endpoint.  


If the <i>X-UserAgent-ID</i> is not provided, the UserAgent is presumed to be new and a new UAID will be generated for the UserAgent.
If the <i>X-UserAgent-ID</i> is not provided, the UserAgent is presumed to be new and a new UAID will be generated for the UserAgent.
Line 144: Line 164:


===== Returns =====
===== Returns =====
  { "channelID": "New Channel ID",  
  { "channelID": "<channelID provided by UA>",  
  "pushEndpoint": "http://pushserver.provider.tld/path/to/notify"
   "uaid": "UserAgent ID" (optional)
   "uaid": "UserAgent ID" (optional)
  }
  }


NOTE: The uaid is either the X-UserAgent-ID value echoed back, or a new X-UserAgent-ID value to be used for all subsequent calls if no X-UserAgent-ID was present.
NOTE: The uaid is either the X-UserAgent-ID value echoed back, or a new X-UserAgent-ID value to be used for all subsequent calls if no X-UserAgent-ID was present.
pushEndpoint may incorporate channelID to simplify implementation and reduce state storage at server.


===== Errors =====
===== Errors =====
Line 156: Line 179:


===== Example =====
===== Example =====
  GET http://push.m.o/v1/register  
  GET http://push.services.mozilla.org/v1/register/foo1234
  ---
  ---
  {"channelID": "foo1234", "uaid": "bar5678"}
  {"channelID": "foo1234", "pushEndpoint": "http://push5.services.mozilla.org/v1/update/foo1234", "uaid": "bar5678"}


==== DELETE /v1/<ChannelID> ====
==== DELETE /v1/<ChannelID> ====
Line 197: Line 220:
* <tt>expired</tt> - A list of ChannelIDs which have expired. The UA should remove these from its own database, and ask applications to re-register.
* <tt>expired</tt> - A list of ChannelIDs which have expired. The UA should remove these from its own database, and ask applications to re-register.


'''TODO''' Do we need acknowledgement of the /update from the UA. It is possible for the response to be lost in flight.
'''TODO''' We need acknowledgement of the /update from the UA. It is possible for the response to be lost in flight and we're trying for reliable delivery.


NOTE: If the server is unable to determine previous data for this X-UserAgent-ID, it will return a 410 leading to the Registration Sync Protocol occurring.  
NOTE: If the server is unable to determine previous data for this X-UserAgent-ID, it will return a 410 leading to the Registration Sync Protocol occurring.  
Line 215: Line 238:


The UserAgent '''SHOULD'''
The UserAgent '''SHOULD'''
# Send a list of <channelID, version> pairs capturing its current state to PushServer, along with the UAID.
# Send a list of <channelID, pushEndpoint, version> pairs capturing its current state to PushServer, along with the UAID.
# If the PushServer accepts the request, it SHOULD update its records. UserAgent and PushServer are now back in sync. DONE
# If the PushServer accepts the request, it SHOULD update its records. UserAgent and PushServer are now back in sync. DONE
# If the PushServer detects a duplicate UAID, it SHOULD respond with an error.
# If the PushServer detects a duplicate UAID, it SHOULD respond with an error.
Line 224: Line 247:
<pre>
<pre>
{
{
   "channels": [{"channelID": "channelID1", "version": "version1"}, {"channelID": "channelID2", "version": "version2"}, ...]
   "channels": [{"channelID": "channelID1", "pushEndpoint": "...", "version": "version1"}, {"channelID": "channelID2", "pushEndpoint": "...", "version": "version2"}, ...]
}
}
</pre>
</pre>
Line 266: Line 289:
In the event of a PushServer catastrophe, the PushServer will be in "Recovery" mode. During this time, unresolvable ChannelIDs will return a 503 error.
In the event of a PushServer catastrophe, the PushServer will be in "Recovery" mode. During this time, unresolvable ChannelIDs will return a 503 error.


In non-recovery mode, unresolvable ChannelIDs will return a 404.
In non-recovery mode, unresolvable pushEndpoints will return a 404.
In this case, the app server should remove the endpoint association
 
A case can occur where the server starts in recovery mode, then after a sufficient period of time switches to non-recovery mode, but a particular UA has still not pinged it (perhaps because the UA does not have Internet access). In this case, application servers may have removed endpoint associations, so the push server needs to inform the UA about which channels were updated, but returned a 404. The UA will then request those apps to re-register.
 
The alternative to this 2 step recovery is to require all pushEndpoints to 404, and on Registration Sync, '''all apps''' are told to register again using 'push-register'.


This call returns an empty JSON object.
This call returns an empty JSON object.
Confirmed users
93

edits

Navigation menu