mirror of
https://github.com/socketio/socket.io.git
synced 2026-04-30 03:00:39 -04:00
260 lines
4.8 KiB
JavaScript
260 lines
4.8 KiB
JavaScript
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
var WS = require('./websocket')
|
|
, util = require('../util')
|
|
, debug = require('debug')('engine.io-client:flashsocket');
|
|
|
|
/**
|
|
* Module exports.
|
|
*/
|
|
|
|
module.exports = FlashWS;
|
|
|
|
/**
|
|
* Global reference.
|
|
*/
|
|
|
|
var global = util.global()
|
|
|
|
/**
|
|
* Obfuscated key for Blue Coat.
|
|
*/
|
|
|
|
var xobject = global[['Active'].concat('Object').join('X')];
|
|
|
|
/**
|
|
* FlashWS constructor.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
function FlashWS (options) {
|
|
WS.call(this, options);
|
|
this.flashPath = options.flashPath;
|
|
this.policyPort = options.policyPort;
|
|
};
|
|
|
|
/**
|
|
* Inherits from WebSocket.
|
|
*/
|
|
|
|
util.inherits(FlashWS, WS);
|
|
|
|
/**
|
|
* Transport name.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
FlashWS.prototype.name = 'flashsocket';
|
|
|
|
/**
|
|
* Opens the transport.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
FlashWS.prototype.doOpen = function () {
|
|
if (!this.check()) {
|
|
// let the probe timeout
|
|
return;
|
|
}
|
|
|
|
// instrument websocketjs logging
|
|
function log (type) {
|
|
return function(){
|
|
var str = Array.prototype.join.call(arguments, ' ');
|
|
debug('[websocketjs %s] %s', type, str);
|
|
};
|
|
};
|
|
|
|
WEB_SOCKET_LOGGER = { log: log('debug'), error: log('error') };
|
|
WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;
|
|
WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = true;
|
|
|
|
if ('undefined' == typeof WEB_SOCKET_SWF_LOCATION) {
|
|
WEB_SOCKET_SWF_LOCATION = this.flashPath + 'WebSocketMainInsecure.swf';
|
|
}
|
|
|
|
// dependencies
|
|
var deps = [this.flashPath + 'web_socket.js'];
|
|
|
|
if ('undefined' == typeof swfobject) {
|
|
deps.unshift(this.flashPath + 'swfobject.js');
|
|
}
|
|
|
|
var self = this;
|
|
|
|
load(deps, function () {
|
|
self.ready(function () {
|
|
WebSocket.__addTask(function () {
|
|
WS.prototype.doOpen.call(self);
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Override to prevent closing uninitialized flashsocket.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
FlashWS.prototype.doClose = function () {
|
|
if (!this.socket) return;
|
|
var self = this;
|
|
WebSocket.__addTask(function() {
|
|
WS.prototype.doClose.call(self);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Writes to the Flash socket.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
FlashWS.prototype.write = function() {
|
|
var self = this, args = arguments;
|
|
WebSocket.__addTask(function () {
|
|
WS.prototype.write.apply(self, args);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Called upon dependencies are loaded.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
FlashWS.prototype.ready = function (fn) {
|
|
if (typeof WebSocket == 'undefined' ||
|
|
!('__initialize' in WebSocket) || !swfobject) {
|
|
return;
|
|
}
|
|
|
|
if (swfobject.getFlashPlayerVersion().major < 10) {
|
|
return;
|
|
}
|
|
|
|
function init () {
|
|
// Only start downloading the swf file when the checked that this browser
|
|
// actually supports it
|
|
if (!FlashWS.loaded) {
|
|
if (843 != self.policyPort) {
|
|
WebSocket.loadFlashPolicyFile('xmlsocket://' + self.host + ':' + self.policyPort);
|
|
}
|
|
|
|
WebSocket.__initialize();
|
|
FlashWS.loaded = true;
|
|
}
|
|
|
|
fn.call(self);
|
|
}
|
|
|
|
var self = this;
|
|
if (document.body) {
|
|
return init();
|
|
}
|
|
|
|
util.load(init);
|
|
};
|
|
|
|
/**
|
|
* Feature detection for flashsocket.
|
|
*
|
|
* @return {Boolean} whether this transport is available.
|
|
* @api public
|
|
*/
|
|
|
|
FlashWS.prototype.check = function () {
|
|
if ('undefined' == typeof window) {
|
|
return false;
|
|
}
|
|
|
|
if (typeof WebSocket != 'undefined' && !('__initialize' in WebSocket)) {
|
|
return false;
|
|
}
|
|
|
|
if (xobject) {
|
|
var control = null;
|
|
try {
|
|
control = new xobject('ShockwaveFlash.ShockwaveFlash');
|
|
} catch (e) { }
|
|
if (control) {
|
|
return true;
|
|
}
|
|
} else {
|
|
for (var i = 0, l = navigator.plugins.length; i < l; i++) {
|
|
for (var j = 0, m = navigator.plugins[i].length; j < m; j++) {
|
|
if (navigator.plugins[i][j].description == 'Shockwave Flash') {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Lazy loading of scripts.
|
|
* Based on $script by Dustin Diaz - MIT
|
|
*/
|
|
|
|
var scripts = {};
|
|
|
|
/**
|
|
* Injects a script. Keeps tracked of injected ones.
|
|
*
|
|
* @param {String} path
|
|
* @param {Function} callback
|
|
* @api private
|
|
*/
|
|
|
|
function create (path, fn) {
|
|
if (scripts[path]) return fn();
|
|
|
|
var el = document.createElement('script');
|
|
var loaded = false;
|
|
|
|
debug('loading "%s"', path);
|
|
el.onload = el.onreadystatechange = function () {
|
|
if (loaded || scripts[path]) return;
|
|
var rs = el.readyState;
|
|
if (!rs || 'loaded' == rs || 'complete' == rs) {
|
|
debug('loaded "%s"', path);
|
|
el.onload = el.onreadystatechange = null;
|
|
loaded = true;
|
|
scripts[path] = true;
|
|
fn();
|
|
}
|
|
};
|
|
|
|
el.async = 1;
|
|
el.src = path;
|
|
|
|
var head = document.getElementsByTagName('head')[0];
|
|
head.insertBefore(el, head.firstChild);
|
|
};
|
|
|
|
/**
|
|
* Loads scripts and fires a callback.
|
|
*
|
|
* @param {Array} paths
|
|
* @param {Function} callback
|
|
*/
|
|
|
|
function load (arr, fn) {
|
|
function process (i) {
|
|
if (!arr[i]) return fn();
|
|
create(arr[i], function () {
|
|
process(++i);
|
|
});
|
|
};
|
|
|
|
process(0);
|
|
};
|