| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 | 
							- /**
 
-  * Socket implementation that uses flash SocketPool class as a backend.
 
-  *
 
-  * @author Dave Longley
 
-  *
 
-  * Copyright (c) 2010-2013 Digital Bazaar, Inc.
 
-  */
 
- var forge = require('./forge');
 
- require('./util');
 
- // define net namespace
 
- var net = module.exports = forge.net = forge.net || {};
 
- // map of flash ID to socket pool
 
- net.socketPools = {};
 
- /**
 
-  * Creates a flash socket pool.
 
-  *
 
-  * @param options:
 
-  *          flashId: the dom ID for the flash object element.
 
-  *          policyPort: the default policy port for sockets, 0 to use the
 
-  *            flash default.
 
-  *          policyUrl: the default policy file URL for sockets (if provided
 
-  *            used instead of a policy port).
 
-  *          msie: true if the browser is msie, false if not.
 
-  *
 
-  * @return the created socket pool.
 
-  */
 
- net.createSocketPool = function(options) {
 
-   // set default
 
-   options.msie = options.msie || false;
 
-   // initialize the flash interface
 
-   var spId = options.flashId;
 
-   var api = document.getElementById(spId);
 
-   api.init({marshallExceptions: !options.msie});
 
-   // create socket pool entry
 
-   var sp = {
 
-     // ID of the socket pool
 
-     id: spId,
 
-     // flash interface
 
-     flashApi: api,
 
-     // map of socket ID to sockets
 
-     sockets: {},
 
-     // default policy port
 
-     policyPort: options.policyPort || 0,
 
-     // default policy URL
 
-     policyUrl: options.policyUrl || null
 
-   };
 
-   net.socketPools[spId] = sp;
 
-   // create event handler, subscribe to flash events
 
-   if(options.msie === true) {
 
-     sp.handler = function(e) {
 
-       if(e.id in sp.sockets) {
 
-         // get handler function
 
-         var f;
 
-         switch(e.type) {
 
-         case 'connect':
 
-           f = 'connected';
 
-           break;
 
-         case 'close':
 
-           f = 'closed';
 
-           break;
 
-         case 'socketData':
 
-           f = 'data';
 
-           break;
 
-         default:
 
-           f = 'error';
 
-           break;
 
-         }
 
-         /* IE calls javascript on the thread of the external object
 
-           that triggered the event (in this case flash) ... which will
 
-           either run concurrently with other javascript or pre-empt any
 
-           running javascript in the middle of its execution (BAD!) ...
 
-           calling setTimeout() will schedule the javascript to run on
 
-           the javascript thread and solve this EVIL problem. */
 
-         setTimeout(function() {sp.sockets[e.id][f](e);}, 0);
 
-       }
 
-     };
 
-   } else {
 
-     sp.handler = function(e) {
 
-       if(e.id in sp.sockets) {
 
-         // get handler function
 
-         var f;
 
-         switch(e.type) {
 
-         case 'connect':
 
-           f = 'connected';
 
-           break;
 
-         case 'close':
 
-           f = 'closed';
 
-           break;
 
-         case 'socketData':
 
-           f = 'data';
 
-           break;
 
-         default:
 
-           f = 'error';
 
-           break;
 
-         }
 
-         sp.sockets[e.id][f](e);
 
-       }
 
-     };
 
-   }
 
-   var handler = 'forge.net.socketPools[\'' + spId + '\'].handler';
 
-   api.subscribe('connect', handler);
 
-   api.subscribe('close', handler);
 
-   api.subscribe('socketData', handler);
 
-   api.subscribe('ioError', handler);
 
-   api.subscribe('securityError', handler);
 
-   /**
 
-    * Destroys a socket pool. The socket pool still needs to be cleaned
 
-    * up via net.cleanup().
 
-    */
 
-   sp.destroy = function() {
 
-     delete net.socketPools[options.flashId];
 
-     for(var id in sp.sockets) {
 
-       sp.sockets[id].destroy();
 
-     }
 
-     sp.sockets = {};
 
-     api.cleanup();
 
-   };
 
-   /**
 
-    * Creates a new socket.
 
-    *
 
-    * @param options:
 
-    *          connected: function(event) called when the socket connects.
 
-    *          closed: function(event) called when the socket closes.
 
-    *          data: function(event) called when socket data has arrived,
 
-    *            it can be read from the socket using receive().
 
-    *          error: function(event) called when a socket error occurs.
 
-    */
 
-    sp.createSocket = function(options) {
 
-      // default to empty options
 
-      options = options || {};
 
-      // create flash socket
 
-      var id = api.create();
 
-      // create javascript socket wrapper
 
-      var socket = {
 
-        id: id,
 
-        // set handlers
 
-        connected: options.connected || function(e) {},
 
-        closed: options.closed || function(e) {},
 
-        data: options.data || function(e) {},
 
-        error: options.error || function(e) {}
 
-      };
 
-      /**
 
-       * Destroys this socket.
 
-       */
 
-      socket.destroy = function() {
 
-        api.destroy(id);
 
-        delete sp.sockets[id];
 
-      };
 
-      /**
 
-       * Connects this socket.
 
-       *
 
-       * @param options:
 
-       *          host: the host to connect to.
 
-       *          port: the port to connect to.
 
-       *          policyPort: the policy port to use (if non-default), 0 to
 
-       *            use the flash default.
 
-       *          policyUrl: the policy file URL to use (instead of port).
 
-       */
 
-      socket.connect = function(options) {
 
-        // give precedence to policy URL over policy port
 
-        // if no policy URL and passed port isn't 0, use default port,
 
-        // otherwise use 0 for the port
 
-        var policyUrl = options.policyUrl || null;
 
-        var policyPort = 0;
 
-        if(policyUrl === null && options.policyPort !== 0) {
 
-          policyPort = options.policyPort || sp.policyPort;
 
-        }
 
-        api.connect(id, options.host, options.port, policyPort, policyUrl);
 
-      };
 
-      /**
 
-       * Closes this socket.
 
-       */
 
-      socket.close = function() {
 
-        api.close(id);
 
-        socket.closed({
 
-          id: socket.id,
 
-          type: 'close',
 
-          bytesAvailable: 0
 
-        });
 
-      };
 
-      /**
 
-       * Determines if the socket is connected or not.
 
-       *
 
-       * @return true if connected, false if not.
 
-       */
 
-      socket.isConnected = function() {
 
-        return api.isConnected(id);
 
-      };
 
-      /**
 
-       * Writes bytes to this socket.
 
-       *
 
-       * @param bytes the bytes (as a string) to write.
 
-       *
 
-       * @return true on success, false on failure.
 
-       */
 
-      socket.send = function(bytes) {
 
-        return api.send(id, forge.util.encode64(bytes));
 
-      };
 
-      /**
 
-       * Reads bytes from this socket (non-blocking). Fewer than the number
 
-       * of bytes requested may be read if enough bytes are not available.
 
-       *
 
-       * This method should be called from the data handler if there are
 
-       * enough bytes available. To see how many bytes are available, check
 
-       * the 'bytesAvailable' property on the event in the data handler or
 
-       * call the bytesAvailable() function on the socket. If the browser is
 
-       * msie, then the bytesAvailable() function should be used to avoid
 
-       * race conditions. Otherwise, using the property on the data handler's
 
-       * event may be quicker.
 
-       *
 
-       * @param count the maximum number of bytes to read.
 
-       *
 
-       * @return the bytes read (as a string) or null on error.
 
-       */
 
-      socket.receive = function(count) {
 
-        var rval = api.receive(id, count).rval;
 
-        return (rval === null) ? null : forge.util.decode64(rval);
 
-      };
 
-      /**
 
-       * Gets the number of bytes available for receiving on the socket.
 
-       *
 
-       * @return the number of bytes available for receiving.
 
-       */
 
-      socket.bytesAvailable = function() {
 
-        return api.getBytesAvailable(id);
 
-      };
 
-      // store and return socket
 
-      sp.sockets[id] = socket;
 
-      return socket;
 
-   };
 
-   return sp;
 
- };
 
- /**
 
-  * Destroys a flash socket pool.
 
-  *
 
-  * @param options:
 
-  *          flashId: the dom ID for the flash object element.
 
-  */
 
- net.destroySocketPool = function(options) {
 
-   if(options.flashId in net.socketPools) {
 
-     var sp = net.socketPools[options.flashId];
 
-     sp.destroy();
 
-   }
 
- };
 
- /**
 
-  * Creates a new socket.
 
-  *
 
-  * @param options:
 
-  *          flashId: the dom ID for the flash object element.
 
-  *          connected: function(event) called when the socket connects.
 
-  *          closed: function(event) called when the socket closes.
 
-  *          data: function(event) called when socket data has arrived, it
 
-  *            can be read from the socket using receive().
 
-  *          error: function(event) called when a socket error occurs.
 
-  *
 
-  * @return the created socket.
 
-  */
 
- net.createSocket = function(options) {
 
-   var socket = null;
 
-   if(options.flashId in net.socketPools) {
 
-     // get related socket pool
 
-     var sp = net.socketPools[options.flashId];
 
-     socket = sp.createSocket(options);
 
-   }
 
-   return socket;
 
- };
 
 
  |