UNPKG

thali

Version:
920 lines (354 loc) 26.1 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Class: TCPServersManager</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">Class: TCPServersManager</h1> <section> <header> <h2> <span class="ancestors"><a href="module-TCPServersManager.html">TCPServersManager</a>~</span>TCPServersManager</h2> </header> <article> <div class="container-overview"> <h4 class="name" id="TCPServersManager"><span class="type-signature"></span>new TCPServersManager<span class="signature">(routerPort)</span><span class="type-signature"></span></h4> <div class="description"> <p>An instance of this class is used by <a href="module-thaliMobileNativeWrapper.html">module:thaliMobileNativeWrapper</a> to create the TCP servers needed to handle non-TCP incoming and outgoing connections.</p> </div> <h5>Parameters:</h5> <table class="params"> <thead> <tr> <th>Name</th> <th>Type</th> <th class="last">Description</th> </tr> </thead> <tbody> <tr> <td class="name"><code>routerPort</code></td> <td class="type"> <span class="param-type">number</span> </td> <td class="description last"><p>The port that the system is hosting the local router instance for the Thali Application.</p></td> </tr> </tbody> </table> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="NextGeneration_TCPServersManager.js.html">NextGeneration/TCPServersManager.js</a>, <a href="NextGeneration_TCPServersManager.js.html#line497">line 497</a> </li></ul></dd> </dl> <h5>Fires:</h5> <ul> <li><a href="module-TCPServersManager.html#~event:routerPortConnectionFailed">event:routerPortConnectionFailed</a></li> <li><a href="module-TCPServersManager.html#~event:failedConnection">event:failedConnection</a></li> </ul> </div> <h3 class="subsection-title">Methods</h3> <h4 class="name" id="createNativeListener"><span class="type-signature">(private) </span>createNativeListener<span class="signature">(routerPort)</span><span class="type-signature"> &rarr; {Promise.&lt;(number|Error)>}</span></h4> <div class="description"> <p>This method creates a TCP listener to handle requests from the native layer and to then pass them through a multiplex object who will route all the multiplexed connections to routerPort, the port the system has hosted the submitted router object on. The TCP listener will be started on port 0 and the port it is hosted on will be returned in the promise. This is the port that MUST be submitted to the native layer's llNative command.</p> <p>If this method is called when we are not in the start state then an exception MUST be thrown because this is a private method and something very bad just happened.</p> <p>If this method is called twice an exception MUST be thrown because this should only be called once from the constructor.</p> <h2>TCP Listener</h2><h3>Connect Event</h3><p>A multiplex object MUST be created and MUST be directly piped in both directions with the TCP socket returned by the listener. We MUST set a timeout on the incoming TCP socket to a reasonable value for the platform. The created multiplex object MUST be recorded with an index of the client port used by the incoming TCP socket.</p> <h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>We MUST call destroy on all multiplex objects spawned by this TCP listener.</p> <h2>Incoming TCP socket returned by the server's connect event</h2><h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Timeout Event</h3><p>Destroy MUST be called on the piped multiplex object. This will trigger a total cleanup.</p> <h3>Close Event</h3><p>If this close is not the result of a destroy on the multiplex object then destroy MUST be called on the multiplex object.</p> <h2>Multiplex Object</h2><h3>onStream Callback</h3><p>The incoming stream MUST cause us to create a net.createConnection to routerPort and to then take the new TCP socket and pipe it in both directions with the newly created stream. We MUST track the TCP socket so we can clean it up later. Note that the TCP socket will track its associated stream and handle cleaning it up. If the TCP socket cannot be connected to routerPort then a routerPortConnectionFailed event MUST be fired and destroy MUST be called on the stream provided in the callback.</p> <h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>Destroy MUST first be called on all the TCP sockets we created to routerPort (the TCP sockets will then close their associated multiplex streams). Then we MUST call Destroy on the incoming TCP socket from the native layer. Note that in some cases one or more of these objects could already be closed before we call destroy so we MUST be prepared to catch any exceptions. Finally we MUST remove the multiplex object from the list of multiplex objects we are maintaining.</p> <h2>TCP client socket created by net.createConnection call from multiplex</h2><p>object</p> <h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>Destroy MUST be called on the stream this TCP socket is piped to assuming that it wasn't that stream that called destroy on the TCP client socket.</p> <h2>multiplex onStream stream</h2><h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>If the close did not come from the TCP socket this stream is piped to then close MUST be called on the associated TCP socket.</p> </div> <h5>Parameters:</h5> <table class="params"> <thead> <tr> <th>Name</th> <th>Type</th> <th class="last">Description</th> </tr> </thead> <tbody> <tr> <td class="name"><code>routerPort</code></td> <td class="type"> <span class="param-type">number</span> </td> <td class="description last"><p>Port that the router object submitted to module:ThaliMobileNativeWrapper.startUpdateAdvertisingAndListening is hosted on. This value was passed into this object's constructor.</p></td> </tr> </tbody> </table> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="NextGeneration_TCPServersManager.js.html">NextGeneration/TCPServersManager.js</a>, <a href="NextGeneration_TCPServersManager.js.html#line269">line 269</a> </li></ul></dd> </dl> <h5>Returns:</h5> <div class="param-desc"> <p>The port that the mux is listening on for connections from the native layer or an Error object.</p> </div> <dl> <dt> Type </dt> <dd> <span class="param-type">Promise.&lt;(number|Error)></span> </dd> </dl> <h4 class="name" id="createPeerListener"><span class="type-signature"></span>createPeerListener<span class="signature">(peerIdentifier, pleaseConnect<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Promise.&lt;(number|Error)>}</span></h4> <div class="description"> <p>This creates a local TCP server to accept incoming connections from the Thali app that will be sent to the identified peer.</p> <p>If this method is called before start is called then a &quot;Start First!&quot; error MUST be thrown. If this method is called after stop is called then a &quot;We are stopped!&quot; error MUST be thrown.</p> <p>If there is already a TCP server listening for connections to the submitted peerIdentifier then the port for the TCP server MUST be returned.</p> <p>If there is no existing TCP server for the specified peer then we MUST examine how many peers we are advertising 127.0.0.1 ports for. If that number is equal to maxPeersToAdvertise then we MUST call destroy on one of those TCP listeners before continuing with this method. That way we will never offer connections to more than maxPeersToAdvertise peers at a time. We should exclude all TCP servers that have active multiplex objects and pick a TCP server to close based on FIFO. Once we have closed the TCP server, if necessary, then a new TCP server MUST be created on port 0 (e.g. any available port) and configured as follows:</p> <h2>TCP server</h2><p>If pleaseConnect is true then an immediate call MUST be made to external:&quot;Mobile('connect')&quot;.callNative to connect to the specified peer. If that call fails then the error MUST be returned. Otherwise a new multiplex object MUST be created and a new TCP connection via net.createConnection pointed at the port returned by the connect call. The multiplex object MUST be piped in both directions with the new TCP connection. The TCP connection MUST have setTimeout called on it and set to a reasonable value for the platform.</p> <h3>Connection Event</h3><h4>First call to connection event when pleaseConnect is false</h4><p>If pleaseConnect is false then when the first connection event occurs we MUST issue a external:&quot;Mobile('connect')&quot;.callNative for the requested peer and handle the response as given in the following sections.</p> <h5>Error</h5><p>If we get an error then we MUST close the TCP connection and fire a <a href="module-TCPServersManager.html#~event:failedConnection">event:failedConnection</a> event with the returned error.</p> <h5>listenerPort</h5><p>If the response is listenerPort then we MUST perform the actions specified above for pleaseConnect is true with the exception that if the connect fails then we MUST call close on the TCP server since the peer is not available and fire a <a href="module-TCPServersManager.html#~event:failedConnection">event:failedConnection</a> event with the error set to &quot;Cannot Connect To Peer&quot;.</p> <h5>clientPort/serverPort</h5><p>If clientPort/serverPort are not null then we MUST confirm that the serverPort matches the port that the server created in module:TCPServersManager.createNativeListener is listening on and if not then we MUST call destroy on the incoming TCP connection, fire a <a href="module-TCPServersManager.html#~event:failedConnection">event:failedConnection</a> event with the error set to &quot;Mismatched serverPort&quot;, and act as if connection had not been called (e.g. the next connection will be treated as the first).</p> <p>Otherwise we must then lookup the multiplex object via the clientPort. If there is no multiplex object associated with that clientPort then we have a race condition where the incoming connection died between when the connect response was sent and now. In that case we MUST call destroy on the incoming TCP connection, first a <a href="module-TCPServersManager.html#~event:failedConnection">event:failedConnection</a> event with the error set to &quot;Incoming connection died&quot; and as previously described treat the next connection as if it were the first.</p> <p>Otherwise we MUST configure the multiplex object with the behavior specified below.</p> <h4>Standard connection event behavior</h4><p>Each socket returned by the connection event MUST cause a call to createStream on the multiplex object and the returned stream MUST be piped in both directions with the connection TCP socket.</p> <h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>All the TCP sockets to routerPort MUST first be destroyed. Then all the TCP sockets from the Thali application MUST be destroyed.</p> <p>Unless destroy was called on the TCP server by the multiplex object then destroy MUST be called on the multiplex object.</p> <h2>Multiplex object</h2><h3>onStream callback</h3><p>If a stream is received a call to net.createConnection MUST be made pointed at routerPort. If the TCP connection cannot be successfully connected then a <a href="module-TCPServersManager.html#~event:routerPortConnectionFailed">event:routerPortConnectionFailed</a> MUST be fired and destroy MUST be called on the stream. Otherwise the TCP connection and the stream MUST be piped to each other in both directions.</p> <p>Note that we will support the ability to accept incoming connections over the multiplex object even for platforms like Android that do not need it. This is just to keep the code and testing simple and consistent.</p> <h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>If the destroy didn't come the TCP server then destroy MUST be called on the TCP server. If the destroy didn't come from the TCP native socket then destroy MUST be called on the TCP native socket.</p> <h2>TCP socket to native layer</h2><h3>Timeout Event</h3><p>Destroy MUST be called on itself.</p> <h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>Destroy MUST be called on the multiplex object the stream is piped to.</p> <h2>TCP socket from Thali Application</h2><h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>Destroy MUST be called on the stream object the socket is piped to if that isn't the object that called destroy on the socket.</p> <h2>createStream Socket</h2><h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>If destroy wasn't called by the TCP socket from Thali Application the stream is piped to then destroy MUST be called on that TCP socket.</p> <h2>TCP socket to routerPort</h2><h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>Destroy MUST be called on the stream object the socket is piped to if that isn't the object that called destroy on the socket.</p> <h2>onStream callback stream</h2><h3>Error Event</h3><p>The error MUST be logged.</p> <h3>Close Event</h3><p>If destroy wasn't called by the TCP socket to routerPort the stream is piped to then destroy MUST be called on that TCP socket.</p> </div> <h5>Parameters:</h5> <table class="params"> <thead> <tr> <th>Name</th> <th>Type</th> <th>Attributes</th> <th class="last">Description</th> </tr> </thead> <tbody> <tr> <td class="name"><code>peerIdentifier</code></td> <td class="type"> <span class="param-type">string</span> </td> <td class="attributes"> </td> <td class="description last"></td> </tr> <tr> <td class="name"><code>pleaseConnect</code></td> <td class="type"> <span class="param-type">boolean</span> </td> <td class="attributes"> &lt;optional><br> </td> <td class="description last"><p>If set to true this indicates that a lexically smaller peer asked for a connection so the lexically larger peer (the local device) will immediately call external:&quot;Mobile('connect')&quot;.callNative to create a connection. If false (the default value) then the call to external:&quot;Mobile('connect')&quot;.callNative will only happen on the first incoming connection to the TCP server.</p></td> </tr> </tbody> </table> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="NextGeneration_TCPServersManager.js.html">NextGeneration/TCPServersManager.js</a>, <a href="NextGeneration_TCPServersManager.js.html#line458">line 458</a> </li></ul></dd> </dl> <h5>Returns:</h5> <dl> <dt> Type </dt> <dd> <span class="param-type">Promise.&lt;(number|Error)></span> </dd> </dl> <h4 class="name" id="start"><span class="type-signature"></span>start<span class="signature">()</span><span class="type-signature"> &rarr; {Promise.&lt;(number|Error)>}</span></h4> <div class="description"> <p>This method will call <a href="module-TCPServersManager-TCPServersManager.html#createNativeListener">module:TCPServersManager~TCPServersManager#createNativeListener</a> using the routerPort from the constructor and record the returned port.</p> <p>This method is idempotent and so MUST be able to be called multiple times in a row without changing state.</p> <p>If called successfully then the object is in the start state.</p> <p>If this method is called after a call to TCPServersManager~TCPServersManager#stop then a &quot;We are stopped!&quot; error MUST be thrown.</p> </div> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="NextGeneration_TCPServersManager.js.html">NextGeneration/TCPServersManager.js</a>, <a href="NextGeneration_TCPServersManager.js.html#line137">line 137</a> </li></ul></dd> </dl> <h5>Returns:</h5> <div class="param-desc"> <p>Returns the port to be passed to llNative when the system is ready to receive external incoming connections.</p> </div> <dl> <dt> Type </dt> <dd> <span class="param-type">Promise.&lt;(number|Error)></span> </dd> </dl> <h4 class="name" id="stop"><span class="type-signature"></span>stop<span class="signature">()</span><span class="type-signature"> &rarr; (nullable) {Error}</span></h4> <div class="description"> <p>This will cause destroy to be called on the TCP server created by module:TCPServersManager.createNativeListener and then on all the TCP servers created by module:TCPServersManager.connectToPeerViaNativeLayer.</p> <p>This method is idempotent and so MUST be able to be called multiple times in a row without changing state.</p> <p>If this method is called before calling start then a &quot;Call Start!&quot; Error MUST be thrown.</p> <p>Once called the object is in the stop state and cannot leave it. To start again this object must be disposed and a new one created.</p> </div> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="NextGeneration_TCPServersManager.js.html">NextGeneration/TCPServersManager.js</a>, <a href="NextGeneration_TCPServersManager.js.html#line159">line 159</a> </li></ul></dd> </dl> <h5>Returns:</h5> <dl> <dt> Type </dt> <dd> <span class="param-type">Error</span> </dd> </dl> </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>