UNPKG

thali

Version:
248 lines (218 loc) 16 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: NextGeneration/thaliNotificationClient.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: NextGeneration/thaliNotificationClient.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>'use strict'; var EventEmitter = require('events'); var thaliPeerDictionary = require('thaliPeerDictionary'); /** @module thaliNotificationClient */ /** * Creates a class that can register to receive the {@link * module:thaliMobile.event:peerAvailabilityChanged} event. It will listen for * the event and upon receiving it, will enqueue an action with the * submitted thaliPeerPool. Once called back by the pool then the callback will * issue a HTTP GET request to retrieve the notification beacons for the peer, * parse them, see if one matches and if so then fire a {@link * module:thaliNotificationClient.event:peerAdvertisesDataForUs}. Callers can * listen for the event by using the emitter member. * * @public * @constructor * @param {module:thaliPeerPoolInterface~ThaliPeerPoolInterface} thaliPeerPool * Requests to retrieve notification beacons are enqueued on this object in * order to make sure we don't overwhelm our bandwidth or native communication * capabilities. * @param {Crypto.ECDH} ecdhForLocalDevice A Crypto.ECDH object initialized * with the local device's public and private keys. * @param {addressBookCallback} addressBookCallback An object used to validate * which peers we are interested in talking to. * @fires module:thaliNotificationClient.event:peerAdvertisesDataForUs */ function ThaliNotificationClient(thaliPeerPool, ecdhForLocalDevice, addressBookCallback) { EventEmitter.call(this); this._init(); this.peerDictionary = new thaliPeerDictionary.PeerDictionary(); } /** * A dictionary used to track the state of peers we have received notifications * about from {@link module:thaliMobile}. * * @type {ThaliNotificationClient.PeerDictionary} */ ThaliNotificationClient.prototype.peerDictionary = null; /** * This method will cause a listener to be registered on the global singleton * {@link module:thaliMobile} object for the {@link * module:thaliMobile.event:peerAvailabilityChanged} event. * * This method MUST be idempotent so calling it twice in a row MUST NOT cause * multiple listeners to be registered with thaliMobile. * * ### Handling peerAvailabilityChanged Events * * The notification code is triggered via peerAvailabilityChanged events. In * handling these events remember that our goal is to find the notification * beacons associated with each peerIdentifier. Once we have retrieved the * beacons for a specific peerIdentifier we don't ever need to deal with that * specific peerIdentifier again. If the peer behind the identifier changes * their beacons then we will get a new peerIdentifier. * * + If hostAddress != null * + If this peer is not in the dictionary * + Create a {@link module:thaliNotificationAction~NotificationAction} and * then call enqueue on the submitted {@link * module:thaliPeerPoolInterface~ThaliPeerPoolInterface} object and then * create a new PeerDictionaryEntry object with the peerState set to * enqueued, the peerConnectionDictionary set to a single entry matching the * data in the peerAvailabilityChanged event and the notificationAction set * to the previously created notificationAction object. * + If this peer is in the table * + If this peer has been marked as RESOLVED * + Ignore the event * + If this peer has been marked as CONTROLLED_BY_POOL and the action's * state is QUEUED or if the peer's state is WAITING * + First update the connection dictionary for the peer's entry with the * new data. Then if the connectionType of the new event is TCP_NATIVE and * if the connectionType of the existing action isn't that then kill the * existing action using {@link * module:thaliPeerPoolInterface~ThaliPeerPoolInterface#kill} and create a * new action and enqueue it and update the entry. The point of this * exercise is that we prefer native TCP transport to other options. * + If this peer has been marked as CONTROLLED_BY_POOL and the action's * state is STARTED * + If the connectionType of the event is different than the * connectionType of the action then just update the * peerConnectionDictionary and move on. If the connectionTypes are * identical then kill the existing action as above. If the * peerConnectionDictionary contains a TCP_NATIVE entry then create and * enqueue an action for that. Otherwise take the entry that was just * updated and create and enqueue that as an action. * + If hostAddress == null * + If this peer is not in the table * + This is technically possible in a number of cases. If this happens * then just ignore the event. * + If this peer is in the table * + If this peer has been marked as resolved * + Ignore the event. * + If this peer has been marked as CONTROLLED_BY_POOL and the action's * state is QUEUED or if the peer's state is WAITING or if this peer has * been marked as CONTROLLED_BY_POOL and the action's state is STARTED * + Call kill on the action via {@link * module:thaliPeerPoolInterface~ThaliPeerPoolInterface#kill} and remove * the associated entry in peerConnectionDictionary. If this leaves no * entries in peerConnectionDictionary then remove this table entry in * total from the dictionary. If there is still an entry left then create * a notificationAction for it and enqueue it. * * ## Handling Resolved events from notificationActions * * When creating a notificationAction a listener MUST be placed on that action * to listen for the * {@link module:thaliNotificationAction~NotificationAction.event:Resolved} * event. * * + BEACONS_RETRIEVED_AND_PARSED * + Mark the entry in the dictionary as RESOLVED and fire * {@link module:thaliNotificationClient.event:peerAdvertisesDataForUs} * + BEACONS_RETRIEVED_BUT_BAD * + This indicates a malfunctioning peer. We need to assume they are bad all * up and mark their entry as RESOLVED without taking any further action. This * means we will ignore this peerIdentifier in the future. * + HTTP_BAD_RESPONSE * + This tells us that the peer is there but not in good shape. But we will * give them the benefit of the doubt. We will wait 100 ms if we are in the * foreground and 500 ms if we are in the background (the later only applies * to Android) and then create a new action (remember, prefer TCP_NATIVE) and * then enqueue it. Make sure to set the dictionary entry's state to * WAITING and when the timer is up and we enqueue to CONTROLLED_BY_POOL. * + NETWORK_problem * + Treat the same as HTTP_BAD_RESPONSE * + KILLED * + We MUST check the value of the notificationAction on the associated * dictionary entry with the notificationAction that this handler was created * on. If they are different then this means that this class was the one who * called kill and so we can ignore this event. If they are the same then it * means that the ThaliPeerPoolInterface called kill (due to resource * exhaustion). Having the pool kill us is a pretty extreme event, it means * we have so many peerIdentifiers that we blew up the pool. So at that point * the best thing for us to do is to just delete the entire entry for this * peerIdentifier and move on. * * @public */ ThaliNotificationClient.prototype.start = function () { }; /** * Will remove the listener registered on the global thaliMobile object, if * any. This method MUST be idempotent so calling it multiple times MUST only * cause a single call to removeListener on thaliMobile and only then if there * already was a call to addListener on this object. * * Removing the listener MUST not just stop listening for the event but MUST * also cause all non-resolved entries in the dictionary to either stop * waiting or if under control of the pool to be killed and then their entries * MUST be removed from the peer dictionary. * * @public */ ThaliNotificationClient.prototype.stop = function () { }; /** * This is the action type that will be used by instances of this class when * registering with {@link * module:thaliPeerPoolInterface~ThaliPeerPoolInterface}. * @type {string} * @readonly */ ThaliNotificationClient.ACTION_TYPE = 'GetRequestBeacon'; /** * Fired whenever we discover a peer who is looking for us. * * @public * @event module:thaliNotificationClient.event:peerAdvertisesDataForUs * @type {Object} * @property {buffer} keyId The buffer contains the HKey as defined * [here](https://github.com/thaliproject/thali/blob/gh-pages/pages/documentation/PresenceProtocolForOpportunisticSynching.md#processing-the-pre-amble-and-beacons). * @property {string} pskIdentifyField This is the value to put in the PSK * identity field of the ClientKeyExchange message when establishing a TLS * connection using PSK. This value is generated * @property {buffer} psk This is the calculated pre-shared key that will be * needed to establish a TLS PSK connection. * @property {string} hostAddress The IP/DNS address of the peer * @property {number} portNumber The TCP/IP port at the hostAddress the peer * can be contacted on * @property {number} suggestedTCPTimeout Provides a hint to what time out to * put on the TCP connection. For some transports a handshake can take quite a * long time. */ module.exports = ThaliNotificationClient; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-TCPServersManager.html">TCPServersManager</a></li><li><a href="module-thaliMobile.html">thaliMobile</a></li><li><a href="module-thaliMobileNative.html">thaliMobileNative</a></li><li><a href="module-thaliMobileNativeWrapper.html">thaliMobileNativeWrapper</a></li><li><a href="module-thaliNotificationAction.html">thaliNotificationAction</a></li><li><a href="module-thaliNotificationBeacons.html">thaliNotificationBeacons</a></li><li><a href="module-thaliNotificationClient.html">thaliNotificationClient</a></li><li><a href="module-thaliNotificationServer.html">thaliNotificationServer</a></li><li><a href="module-thaliPeerAction.html">thaliPeerAction</a></li><li><a href="module-thaliPeerDictionary.html">thaliPeerDictionary</a></li><li><a href="module-thaliPeerPoolInterface.html">thaliPeerPoolInterface</a></li><li><a href="module-ThaliWifiInfrastructure.html">ThaliWifiInfrastructure</a></li><li><a href="module-WifiBasedNativeMock.html">WifiBasedNativeMock</a></li></ul><h3>Externals</h3><ul><li><a href="external-_Mobile(_connect_)_.html">Mobile('connect')</a></li><li><a href="external-_Mobile(_discoveryAdvertisingStateUpdateNonTCP_)_.html">Mobile('discoveryAdvertisingStateUpdateNonTCP')</a></li><li><a href="external-_Mobile(_incomingConnectionToPortNumberFailed_)_.html">Mobile('incomingConnectionToPortNumberFailed')</a></li><li><a href="external-_Mobile(_killConnections_)_.html">Mobile('killConnections')</a></li><li><a href="external-_Mobile(_networkChanged_)_.html">Mobile('networkChanged')</a></li><li><a href="external-_Mobile(_peerAvailabilityChanged_)_.html">Mobile('peerAvailabilityChanged')</a></li><li><a href="external-_Mobile(_startListeningForAdvertisements_)_.html">Mobile('startListeningForAdvertisements')</a></li><li><a href="external-_Mobile(_startUpdateAdvertisingAndListening_)_.html">Mobile('startUpdateAdvertisingAndListening')</a></li><li><a href="external-_Mobile(_stopAdvertisingAndListening_)_.html">Mobile('stopAdvertisingAndListening')</a></li><li><a href="external-_Mobile(_stopListeningForAdvertisements_)_.html">Mobile('stopListeningForAdvertisements')</a></li></ul><h3>Classes</h3><ul><li><a href="ConnectionTable.html">ConnectionTable</a></li><li><a href="module-TCPServersManager-TCPServersManager.html">TCPServersManager</a></li><li><a href="module-thaliNotificationAction-NotificationAction.html">NotificationAction</a></li><li><a href="module-thaliNotificationBeacons-ParseBeaconsResponse.html">ParseBeaconsResponse</a></li><li><a href="module-thaliNotificationClient-ThaliNotificationClient.html">ThaliNotificationClient</a></li><li><a href="module-thaliNotificationServer-ThaliNotificationServer.html">ThaliNotificationServer</a></li><li><a href="module-thaliPeerAction-PeerAction.html">PeerAction</a></li><li><a href="module-thaliPeerDictionary-NotificationPeerDictionaryEntry.html">NotificationPeerDictionaryEntry</a></li><li><a href="module-thaliPeerDictionary-PeerConnectionInformation.html">PeerConnectionInformation</a></li><li><a href="module-thaliPeerDictionary-PeerDictionary.html">PeerDictionary</a></li><li><a href="module-thaliPeerPoolInterface-ThaliPeerPoolInterface.html">ThaliPeerPoolInterface</a></li><li><a href="module-ThaliWifiInfrastructure-ThaliWifiInfrastructure.html">ThaliWifiInfrastructure</a></li><li><a href="module-WifiBasedNativeMock-MobileCallInstance.html">MobileCallInstance</a></li><li><a href="module-WifiBasedNativeMock-WifiBasedNativeMock.html">WifiBasedNativeMock</a></li></ul><h3>Events</h3><ul><li><a href="module-thaliMobileNativeWrapper.html#~event:discoveryAdvertisingStateUpdateNonTCPEvent">discoveryAdvertisingStateUpdateNonTCPEvent</a></li><li><a href="module-ThaliWifiInfrastructure.html#~event:discoveryAdvertisingStateUpdateWifiEvent">discoveryAdvertisingStateUpdateWifiEvent</a></li><li><a href="module-TCPServersManager.html#~event:failedConnection">failedConnection</a></li><li><a href="module-thaliMobileNativeWrapper.html#~event:incomingConnectionToPortNumberFailed">incomingConnectionToPortNumberFailed</a></li><li><a href="module-thaliMobileNativeWrapper.html#~event:networkChangedNonTCP">networkChangedNonTCP</a></li><li><a href="module-ThaliWifiInfrastructure.html#~event:networkChangedWifi">networkChangedWifi</a></li><li><a href="module-thaliMobileNativeWrapper.html#~event:nonTCPPeerAvailabilityChangedEvent">nonTCPPeerAvailabilityChangedEvent</a></li><li><a href="module-TCPServersManager.html#~event:routerPortConnectionFailed">routerPortConnectionFailed</a></li><li><a href="module-ThaliWifiInfrastructure.html#~event:wifiPeerAvailabilityChanged">wifiPeerAvailabilityChanged</a></li><li><a href="module-thaliMobile.html#.event:event:discoveryAdvertisingStateUpdate">discoveryAdvertisingStateUpdate</a></li><li><a href="module-thaliMobile.html#.event:event:networkChanged">networkChanged</a></li><li><a href="module-thaliMobile.html#.event:event:peerAvailabilityChanged">peerAvailabilityChanged</a></li><li><a href="module-thaliNotificationAction-NotificationAction.html#.event:event:Resolved">Resolved</a></li><li><a href="module-thaliNotificationClient.html#.event:event:peerAdvertisesDataForUs">peerAdvertisesDataForUs</a></li></ul><h3>Global</h3><ul><li><a href="global.html#getPKCS12Content">getPKCS12Content</a></li><li><a href="global.html#getPublicKeyHash">getPublicKeyHash</a></li><li><a href="global.html#stopThaliReplicationManager">stopThaliReplicationManager</a></li><li><a href="global.html#ThaliEmitter">ThaliEmitter</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Mon Jan 18 2016 11:19:31 GMT+0200 (EET) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>