mirror of
https://github.com/socketio/socket.io.git
synced 2026-04-30 03:00:39 -04:00
269 lines
4.9 KiB
JavaScript
269 lines
4.9 KiB
JavaScript
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
var WS = require('./websocket');
|
|
var util = require('../util');
|
|
var debug = require('debug')('engine.io-client:flashsocket');
|
|
|
|
/**
|
|
* Module exports.
|
|
*/
|
|
|
|
module.exports = FlashWS;
|
|
|
|
/**
|
|
* Global reference.
|
|
*/
|
|
|
|
var global = require('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';
|
|
|
|
/*
|
|
* FlashSockets only support binary as base64 encoded strings
|
|
*/
|
|
|
|
FlashWS.prototype.supportsBinary = false;
|
|
|
|
/**
|
|
* 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);
|
|
};
|
|
}
|
|
|
|
global.WEB_SOCKET_LOGGER = { log: log('debug'), error: log('error') };
|
|
global.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;
|
|
global.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = true;
|
|
|
|
if (!global.WEB_SOCKET_SWF_LOCATION) {
|
|
global.WEB_SOCKET_SWF_LOCATION = this.flashPath + 'WebSocketMainInsecure.swf';
|
|
}
|
|
|
|
// dependencies
|
|
var deps = [this.flashPath + 'web_socket.js'];
|
|
|
|
if (!global.swfobject) {
|
|
deps.unshift(this.flashPath + 'swfobject.js');
|
|
}
|
|
|
|
var self = this;
|
|
|
|
load(deps, function(){
|
|
self.ready(function(){
|
|
WebSocket.__addTask(function () {
|
|
self.ws = new WebSocket(self.uri());
|
|
self.addEventListeners();
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Override to prevent closing uninitialized flashsocket.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
FlashWS.prototype.doClose = function(){
|
|
if (!this.ws) 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) || !global.swfobject) {
|
|
return;
|
|
}
|
|
|
|
if (global.swfobject.getFlashPlayerVersion().major < 10) {
|
|
return;
|
|
}
|
|
|
|
function init () {
|
|
// only start downloading the swf file when
|
|
// we checked that this browser actually supports it
|
|
if (!FlashWS.loaded) {
|
|
if (843 != self.policyPort) {
|
|
var policy = 'xmlsocket://' + self.hostname + ':' + self.policyPort;
|
|
WebSocket.loadFlashPolicyFile(policy);
|
|
}
|
|
|
|
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);
|
|
}
|