/** @ignore */
var Eureca;
(function (Eureca) {
var EObject = (function () {
function EObject() {
}
// Dynamic extend
EObject.prototype.extend = function (options) {
if (options) {
for (var key in options)
this[key] = options[key];
}
};
// Events primitives ======================
EObject.prototype.bind = function (event, fct) {
this._events = this._events || {};
this._events[event] = this._events[event] || [];
this._events[event].push(fct);
};
EObject.prototype.on = function (event, fct) {
this._events = this._events || {};
this._events[event] = this._events[event] || [];
this._events[event].push(fct);
};
EObject.prototype.unbind = function (event, fct) {
this._events = this._events || {};
if (event in this._events === false)
return;
this._events[event].splice(this._events[event].indexOf(fct), 1);
};
EObject.prototype.unbindEvent = function (event) {
this._events = this._events || {};
this._events[event] = [];
};
EObject.prototype.unbindAll = function () {
this._events = this._events || {};
for (var event in this._events)
this._events[event] = false;
};
EObject.prototype.trigger = function (event) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
this._events = this._events || {};
if (event in this._events === false)
return;
for (var i = 0; i < this._events[event].length; i++) {
this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
}
};
EObject.prototype.registerEvent = function (evtname) {
this[evtname] = function (callback, replace) {
if (typeof callback == 'function') {
if (replace)
this.unbindEvent(evtname);
this.bind(evtname, callback);
}
return this;
};
};
EObject.prototype.registerEvents = function (eventsArray) {
for (var i = 0; i < eventsArray.length; i++)
this.registerEvent(eventsArray[i]);
};
return EObject;
})();
Eureca.EObject = EObject;
})(Eureca || (Eureca = {}));
/** @ignore */
var Eureca;
(function (Eureca) {
// Class
var Util = (function () {
function Util() {
}
Util.extend = function (target, extension) {
if (target && extension) {
for (var key in extension)
target[key] = extension[key];
}
};
//Borrowed from RMI.js https://github.com/mmarcon/rmi.js
Util.randomStr = function (length) {
if (length === void 0) { length = 10; }
var rs, i, nextIndex, l, chars = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
rs = '';
for (i = 0; i < length; i++) {
nextIndex = Math.floor(Math.random() * chars.length);
rs += chars[nextIndex];
}
return rs;
};
Util.isNodejs = (typeof exports == 'object' && exports);
return Util;
})();
Eureca.Util = Util;
})(Eureca || (Eureca = {}));
/// <reference path="ISocket.interface.ts" />
/// <reference path="ISocket.interface.ts" />
/// <reference path="IServer.interface.ts" />
/** @ignore */
var Eureca;
(function (Eureca) {
// Class
var Transport = (function () {
function Transport() {
}
Transport.register = function (name, clientScript, createClient, createServer) {
if (this.transports[name] !== undefined)
return false;
this.transports[name] = {
createClient: createClient,
createServer: createServer,
script: clientScript
};
};
Transport.get = function (name) {
if (name != 'webrtc') {
console.log('* using primus:' + name);
//settings.transport = 'primus';
return this.transports['primus'];
}
else {
console.log('* using ' + name);
return this.transports[name];
}
};
Transport.transports = {};
return Transport;
})();
Eureca.Transport = Transport;
})(Eureca || (Eureca = {}));
/// <reference path="../EObject.class.ts" />
/// <reference path="../Util.class.ts" />
/// <reference path="../Transport.ts" />
/// <reference path="../IServer.interface.ts" />
/// <reference path="../ISocket.interface.ts" />
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
/** @ignore */
var Eureca;
(function (Eureca) {
var Transports;
(function (Transports) {
var PrimusTransport;
(function (PrimusTransport) {
if (Eureca.Util.isNodejs) {
Primus = require('primus');
}
var Socket = (function (_super) {
__extends(Socket, _super);
//public webRTCChannel:any;
//private wRTCPeer;
function Socket(socket) {
_super.call(this);
this.socket = socket;
this.eureca = {};
this.request = socket.request;
this.id = socket.id;
//FIXME : with nodejs 0.10.0 remoteAddress of nodejs clients is undefined (this seems to be a engine.io issue)
this.remoteAddress = socket.address;
//this.registerEvents(['open', 'message', 'error', 'close', 'reconnecting']);
this.bindEvents();
}
Socket.prototype.bindEvents = function () {
var _this = this;
this.socket.on('open', function () {
var args = arguments.length > 0 ? Array.prototype.slice.call(arguments, 0) : [];
args.unshift('open');
_this.trigger.apply(_this, args);
});
this.socket.on('data', function () {
var args = arguments.length > 0 ? Array.prototype.slice.call(arguments, 0) : [];
args.unshift('message');
_this.trigger.apply(_this, args);
});
this.socket.on('end', function () {
var args = arguments.length > 0 ? Array.prototype.slice.call(arguments, 0) : [];
args.unshift('close');
_this.trigger.apply(_this, args);
});
this.socket.on('error', function () {
var args = arguments.length > 0 ? Array.prototype.slice.call(arguments, 0) : [];
args.unshift('error');
_this.trigger.apply(_this, args);
});
this.socket.on('reconnecting', function () {
var args = arguments.length > 0 ? Array.prototype.slice.call(arguments, 0) : [];
args.unshift('reconnecting');
_this.trigger.apply(_this, args);
});
};
//public setupWebRTC()
//{
// if (this.wRTCPeer) return;
// var _this = this;
// this.wRTCPeer = new Eureca.Transports.WebRTC.Peer();
// this.wRTCPeer.makeOffer(function(pc) {
// var webRTCSignalReq = {};
// webRTCSignalReq[Eureca.Protocol.signal] = pc.localDescription;
// _this.send(webRTCSignalReq);
// });
//}
Socket.prototype.isAuthenticated = function () {
return this.eureca.authenticated;
};
Socket.prototype.send = function (data /*, webRTC=false*/) {
//if (webRTC && this.webRTCChannel)
//{
// this.webRTCChannel.send(data);
// return;
//}
if (this.socket.send) {
this.socket.send(data);
}
else {
this.socket.write(data);
}
};
Socket.prototype.close = function () {
if (this.socket.end) {
this.socket.end();
}
else {
this.socket.close();
}
};
//deprecated ?
Socket.prototype.onopen = function (callback) {
this.socket.on('open', callback);
};
Socket.prototype.onmessage = function (callback) {
this.socket.on('data', callback);
};
Socket.prototype.onclose = function (callback) {
this.socket.on('end', callback);
};
Socket.prototype.onerror = function (callback) {
this.socket.on('error', callback);
};
Socket.prototype.ondisconnect = function (callback) {
this.socket.on('reconnecting', callback);
};
return Socket;
})(Eureca.EObject);
PrimusTransport.Socket = Socket;
var Server = (function () {
function Server(primus) {
this.primus = primus;
}
//on client connect
Server.prototype.onconnect = function (callback) {
this.primus.on('connection', function (psocket) {
var socket = new Socket(psocket);
//Eureca.Util.extend(iosocket, socket);
callback(socket);
});
};
return Server;
})();
PrimusTransport.Server = Server;
var createServer = function (hook, options) {
if (options === void 0) { options = {}; }
try {
//var primusOptions: any = {};
options.pathname = options.prefix ? '/' + options.prefix : undefined;
var primus = new Primus(hook, options);
// UPDATE: this file is precompiled
// primus.save(__dirname + '/js/primus.js');
var server = new Server(primus);
return server;
}
catch (ex) {
if (ex.name == 'PrimusError' && ex.message.indexOf('Missing dependencies') == 0) {
console.error('Missing ', options.transformer);
process.exit();
}
else {
throw ex;
}
}
};
var createClient = function (uri, options) {
if (options === void 0) { options = {}; }
options.pathname = options.prefix ? '/' + options.prefix : undefined;
options.path = options.prefix ? '/' + options.prefix : undefined;
var socket;
if (Eureca.Util.isNodejs) {
//eioptions.transports = ['websocket', 'polling', 'flashsocket'];
//console.log('connecting to ', uri, options);
var CSocket = Primus.createSocket(options);
socket = new CSocket(uri);
}
else {
console.log('>>> Ezelia : createClient', uri, options);
socket = new Primus(uri, options);
}
var client = new Socket(socket);
//(<any>client).send = socket.send;
//socket.onopen = client.onopen;
//Eureca.Util.extend(socket, client);
return client;
};
Eureca.Transport.register('primus', '/js/primus.js', createClient, createServer);
})(PrimusTransport = Transports.PrimusTransport || (Transports.PrimusTransport = {}));
})(Transports = Eureca.Transports || (Eureca.Transports = {}));
})(Eureca || (Eureca = {}));
/// <reference path="../EObject.class.ts" />
/// <reference path="../Util.class.ts" />
///
var Eureca;
(function (Eureca) {
var Transports;
(function (Transports) {
var WebRTC;
(function (WebRTC) {
var webrtc;
if (Eureca.Util.isNodejs) {
try {
webrtc = require('wrtc');
}
catch (e) {
//console.error("wrtc module not found : WebRTC support will not be available");
//process.exit(e.code);
webrtc = { unavailable: true, error: e };
}
}
var PeerConnection = Eureca.Util.isNodejs ? webrtc.RTCPeerConnection : window['RTCPeerConnection'] || window['mozRTCPeerConnection'] || window['webkitRTCPeerConnection'];
var SessionDescription = Eureca.Util.isNodejs ? webrtc.RTCSessionDescription : window['RTCSessionDescription'] || window['mozRTCSessionDescription'] || window['webkitRTCSessionDescription'];
var Peer = (function (_super) {
__extends(Peer, _super);
function Peer(settings) {
if (settings === void 0) { settings = { reliable: true }; }
_super.call(this);
this.id = Eureca.Util.randomStr(16);
this.pc = null;
this.offer = null;
//private answer = null;
this.channel = null;
this.pendingDataChannels = {};
this.dataChannels = {};
//public dataChannelSettings = {
// 'reliable': {
// ordered: true,
// maxRetransmits: 0
// },
//};
//public pcSettings = [
// {
// "iceServers": [{"url":"stun:stun.l.google.com:19302"}]
// },
// {
// "optional": [{"DtlsSrtpKeyAgreement": false}]
// }
//];
this.cfg = {
"iceServers": [
{ "url": "stun:stun.l.google.com:19302" },
{ url: 'stun:stun1.l.google.com:19302' }]
};
this.channelSettings = {
reliable: true,
ordered: true,
maxRetransmits: null
};
this.lastState = '';
if (webrtc && webrtc.unavailable) {
console.error("wrtc module not found\n");
console.error(" * If you are running Linux or MacOS X please follow instructions here https://github.com/js-platform/node-webrtc to install wrtc\n");
console.error(" * Windows server side WebRTC is not supported yet\n");
process.exit();
}
if (typeof settings.reliable != 'undefined')
this.channelSettings.reliable = settings.reliable;
if (typeof settings.maxRetransmits != 'undefined')
this.channelSettings.maxRetransmits = settings.maxRetransmits;
if (typeof settings.ordered !== 'undefined')
this.channelSettings.ordered = settings.ordered;
//console.log('WebRTC settings = ', settings, this.channelSettings);
}
Peer.prototype.makeOffer = function (callback) {
var _this = this;
var pc = new PeerConnection(this.cfg, this.con);
this.pc = pc;
this.makeDataChannel();
pc.onsignalingstatechange = this.onsignalingstatechange.bind(this);
pc.oniceconnectionstatechange = this.oniceconnectionstatechange.bind(this);
pc.onicegatheringstatechange = this.onicegatheringstatechange.bind(this);
pc.createOffer(function (desc) {
pc.setLocalDescription(desc, function () { });
// We'll pick up the offer text once trickle ICE is complete,
// in onicecandidate.
});
pc.onicecandidate = function (candidate) {
// Firing this callback with a null candidate indicates that
// trickle ICE gathering has finished, and all the candidates
// are now present in pc.localDescription. Waiting until now
// to create the answer saves us from having to send offer +
// answer + iceCandidates separately.
if (candidate.candidate == null) {
if (typeof callback == 'function')
callback(pc);
}
};
};
Peer.prototype.makeDataChannel = function () {
var _this = this;
// If you don't make a datachannel *before* making your offer (such
// that it's included in the offer), then when you try to make one
// afterwards it just stays in "connecting" state forever. This is
// my least favorite thing about the datachannel API.
var channel = this.pc.createDataChannel(this.id, { id: _this.id, reliable: _this.channelSettings.reliable, maxRetransmits: _this.channelSettings.maxRetransmits, ordered: _this.channelSettings.ordered });
this.channel = channel;
channel.onopen = function () {
_this.trigger('open', channel);
};
channel.onmessage = function (evt) {
var data = JSON.parse(evt.data);
_this.trigger('message', data.message);
};
channel.onerror = function (error) { _this.doHandleError(error); };
;
};
Peer.prototype.getAnswer = function (pastedAnswer) {
var data = typeof pastedAnswer == 'string' ? JSON.parse(pastedAnswer) : pastedAnswer;
var answer = new SessionDescription(data);
this.pc.setRemoteDescription(answer);
};
Peer.prototype.getOffer = function (pastedOffer, callback) {
var data = JSON.parse(pastedOffer);
this.offer = new SessionDescription(data);
var pc = new PeerConnection(this.cfg, this.con);
this.pc = pc;
pc.onsignalingstatechange = this.onsignalingstatechange.bind(this);
pc.oniceconnectionstatechange = this.oniceconnectionstatechange.bind(this);
pc.onicegatheringstatechange = this.onicegatheringstatechange.bind(this);
pc.onicecandidate = function (candidate) {
// Firing this callback with a null candidate indicates that
// trickle ICE gathering has finished, and all the candidates
// are now present in pc.localDescription. Waiting until now
// to create the answer saves us from having to send offer +
// answer + iceCandidates separately.
if (candidate.candidate == null) {
if (typeof callback == 'function')
callback(pc.localDescription);
}
};
this.doHandleDataChannels();
};
Peer.prototype.onsignalingstatechange = function (state) {
//console.info('signaling state change:', state);
};
Peer.prototype.oniceconnectionstatechange = function (state) {
var _this = this;
if (this.pc) {
console.info('ice connection state change:', this.pc.iceConnectionState);
this.lastState = this.pc.iceConnectionState;
if (this.stateTimeout != undefined)
clearTimeout(this.stateTimeout);
if (this.pc.iceConnectionState == 'disconnected' || this.pc.iceConnectionState == 'failed') {
this.trigger('disconnected');
}
if (this.pc.iceConnectionState == 'completed' || this.pc.iceConnectionState == 'connected') {
var ackObj = {};
ackObj[Eureca.Protocol.signalACK] = 1;
var maxtries = 10;
var itv = setInterval(function () {
maxtries--;
if (maxtries <= 0) {
clearInterval(itv);
_this.doHandleError('Channel readyState failure ');
return;
}
if (_this.channel.readyState == 'open') {
clearInterval(itv);
_this.channel.send(JSON.stringify(ackObj));
}
}, 500);
}
else {
this.stateTimeout = setTimeout(function () {
console.log('State timeout');
_this.trigger('timeout');
}, 5000);
}
}
//if (this.pc.
};
Peer.prototype.onicegatheringstatechange = function (state) {
//console.info('ice gathering state change:', state);
};
Peer.prototype.doCreateAnswer = function () {
var _this = this;
this.pc.createAnswer(function (desc) { _this.doSetLocalDesc(desc); }, function (error) { _this.doHandleError(error); });
};
Peer.prototype.doSetLocalDesc = function (desc) {
var _this = this;
//this.answer = desc;
this.pc.setLocalDescription(desc, undefined, function (error) { _this.doHandleError(error); });
};
Peer.prototype.doHandleError = function (error) {
this.trigger('error', error);
};
Peer.prototype.doHandleDataChannels = function () {
var _this = this;
//var labels = Object.keys(this.dataChannelSettings);
this.pc.ondatachannel = function (evt) {
var channel = evt.channel;
_this.channel = channel;
var label = channel.label;
_this.pendingDataChannels[label] = channel;
//channel.binaryType = 'arraybuffer';
channel.onopen = function () {
_this.dataChannels[label] = channel;
delete _this.pendingDataChannels[label];
};
channel.onmessage = function (evt) {
var data = JSON.parse(evt.data);
if (data[Eureca.Protocol.signalACK] == 1) {
_this.trigger('open', channel);
}
_this.trigger('message', data.message);
};
channel.onerror = function (error) { _this.doHandleError(error); };
};
this.pc.setRemoteDescription(this.offer, function () { _this.doCreateAnswer(); }, function (error) { _this.doHandleError(error); });
};
return Peer;
})(Eureca.EObject);
WebRTC.Peer = Peer;
})(WebRTC = Transports.WebRTC || (Transports.WebRTC = {}));
})(Transports = Eureca.Transports || (Eureca.Transports = {}));
})(Eureca || (Eureca = {}));
/// <reference path="../EObject.class.ts" />
/// <reference path="../Util.class.ts" />
/// <reference path="../Transport.ts" />
/// <reference path="../IServer.interface.ts" />
/// <reference path="../ISocket.interface.ts" />
/// <reference path="WebRTCPeer.ts" />
/** @ignore */
var Eureca;
(function (Eureca) {
var Transports;
(function (Transports) {
var WebRTCTransport;
(function (WebRTCTransport) {
var qs, http;
if (Eureca.Util.isNodejs) {
qs = require('querystring');
http = require('http');
try {
webrtc = require('wrtc');
}
catch (e) {
//console.error("WebRTC not be available, you need to install wrtc module");
//process.exit(e.code);
webrtc = {};
}
}
var Socket = (function (_super) {
__extends(Socket, _super);
function Socket(socket, peer) {
_super.call(this);
this.socket = socket;
this.peer = peer;
this.eureca = {};
//this.request = socket.request;
this.id = peer && peer.id ? peer.id : Eureca.Util.randomStr(16);
//FIXME : with nodejs 0.10.0 remoteAddress of nodejs clients is undefined (this seems to be a engine.io issue)
//this.remoteAddress = socket.address;
//this.registerEvents(['open', 'message', 'error', 'close', 'reconnecting']);
this.bindEvents();
}
Socket.prototype.update = function (socket) {
if (this.socket != null) {
this.socket.onopen = null;
this.socket.onmessage = null;
this.socket.onclose = null;
this.socket.onerror = null;
}
this.socket = socket;
this.bindEvents();
};
Socket.prototype.bindEvents = function () {
if (this.socket == null)
return;
var _this = this;
this.socket.onopen = function () {
_this.trigger('open');
};
this.socket.onmessage = function (event) {
_this.trigger('message', event.data);
};
this.socket.onclose = function () {
_this.trigger('close');
};
this.socket.onerror = function (error) {
_this.trigger('error', error);
};
//if (this.peer) {
// this.peer.unbindEvent('disconnected');
// this.peer.on('disconnected', function () {
// _this.trigger('close');
// });
//}
/*
this.socket.on('reconnecting', function () {
var args = arguments.length > 0 ? Array.prototype.slice.call(arguments, 0) : [];
args.unshift('reconnecting');
_this.trigger.apply(_this, args);
});
*/
};
Socket.prototype.isAuthenticated = function () {
return this.eureca.authenticated;
};
Socket.prototype.send = function (data) {
//console.log('sending ', data);
if (this.socket == null)
return;
this.socket.send(data);
};
Socket.prototype.close = function () {
this.socket.close();
};
//deprecated ?
Socket.prototype.onopen = function (callback) {
this.on('open', callback);
};
Socket.prototype.onmessage = function (callback) {
this.on('message', callback);
};
Socket.prototype.onclose = function (callback) {
this.on('close', callback);
};
Socket.prototype.onerror = function (callback) {
this.on('error', callback);
};
Socket.prototype.ondisconnect = function (callback) {
//this.socket.on('reconnecting', callback);
};
return Socket;
})(Eureca.EObject);
WebRTCTransport.Socket = Socket;
var Server = (function () {
function Server(server, options) {
this.server = server;
this.serverPeer = new Transports.WebRTC.Peer();
var _this = this;
var app = server;
if (server._events.request !== undefined && server.routes === undefined)
app = server._events.request;
if (app.get && app.post) {
app.post('/webrtc-' + options.prefix, function (request, response) {
_this.processPost(request, response, function () {
//console.log('Got post data', request.post);
var offer = request.post[Eureca.Protocol.signal];
response.writeHead(200, "OK", { 'Content-Type': 'text/plain' });
_this.serverPeer.getOffer(offer, function (desc) {
var resp = {};
resp[Eureca.Protocol.signal] = desc;
response.write(JSON.stringify(resp));
response.end();
});
});
});
}
else {
//we use POST request for webRTC signaling
server.on('request', function (request, response) {
if (request.method === 'POST') {
if (request.url.split('?')[0] === '/webrtc-' + options.prefix) {
_this.processPost(request, response, function () {
//console.log('Got post data', request.post);
var offer = request.post[Eureca.Protocol.signal];
response.writeHead(200, "OK", { 'Content-Type': 'text/plain' });
_this.serverPeer.getOffer(offer, function (desc) {
var resp = {};
resp[Eureca.Protocol.signal] = desc;
response.write(JSON.stringify(resp));
response.end();
});
});
}
}
});
}
}
Server.prototype.processPost = function (request, response, callback) {
var queryData = "";
if (typeof callback !== 'function')
return null;
if (request.method == 'POST') {
request.on('data', function (data) {
queryData += data;
if (queryData.length > 1e6) {
queryData = "";
response.writeHead(413, { 'Content-Type': 'text/plain' }).end();
request.connection.destroy();
}
});
request.on('end', function () {
request.post = qs.parse(queryData);
callback();
});
}
else {
response.writeHead(405, { 'Content-Type': 'text/plain' });
response.end();
}
};
Server.prototype.onconnect = function (callback) {
this.serverPeer.on('open', function (datachannel) {
var socket = new Socket(datachannel);
//Eureca.Util.extend(iosocket, socket);
callback(socket);
});
};
return Server;
})();
WebRTCTransport.Server = Server;
/**
*
*
* @param hook - eureca server
*/
var createServer = function (hook, options) {
try {
var server = new Server(hook, options);
return server;
}
catch (ex) {
}
};
var createClient = function (uri, options) {
if (options === void 0) { options = {}; }
options.pathname = options.prefix ? '/' + options.prefix : undefined;
options.path = options.prefix ? '/' + options.prefix : undefined;
var clientPeer;
clientPeer = new Transports.WebRTC.Peer(options);
clientPeer.on('disconnected', function () {
clientPeer.channel.close();
signal();
});
var client = new Socket(clientPeer.channel, clientPeer);
var retries = options.retries;
var signal = function () {
if (retries <= 0) {
client.trigger('close');
return;
}
retries--;
clientPeer.makeOffer(function (pc) {
if (Eureca.Util.isNodejs) {
var url = require("url");
var postDataObj = {};
postDataObj[Eureca.Protocol.signal] = JSON.stringify(pc.localDescription);
var post_data = qs.stringify(postDataObj);
var parsedURI = url.parse(uri);
var post_options = {
host: parsedURI.hostname,
port: parsedURI.port,
path: '/webrtc-' + options.prefix,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
}
};
var post_req = http.request(post_options, function (res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
var resp = JSON.parse(chunk);
//console.log('Response: ' + resp['__signal__']);
clientPeer.getAnswer(resp[Eureca.Protocol.signal]);
retries = options.retries;
});
});
post_req.write(post_data);
post_req.end();
post_req.on('error', function (error) {
//console.log('E = ', error);
setTimeout(function () { signal(); }, 3000);
});
}
else {
var xhr = new XMLHttpRequest();
var params = Eureca.Protocol.signal + '=' + JSON.stringify(pc.localDescription);
var parser = document.createElement('a');
parser.href = uri;
//parser.protocol;
//parser.host;
//parser.hostname;
//parser.port;
//parser.pathname;
//parser.hash;
//parser.search;
//var params = "lorem=ipsum&name=binny";
xhr.open("POST", '//' + parser.hostname + ':' + parser.port + '/webrtc-' + options.prefix, true);
//Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//xhr.setRequestHeader("Content-length", params.length.toString());
//xhr.setRequestHeader("Connection", "close");
xhr.onreadystatechange = function () {
//console.log('XHR = ', xhr.readyState, xhr.status);
if (xhr.readyState == 4 && xhr.status == 200) {
var resp = JSON.parse(xhr.responseText);
clientPeer.getAnswer(resp[Eureca.Protocol.signal]);
retries = options.retries;
console.log('Got response ', resp);
}
else {
if (xhr.readyState == 4 && xhr.status != 200) {
setTimeout(function () { signal(); }, 3000);
}
}
};
xhr.send(params);
}
client.update(clientPeer.channel);
});
};
signal();
//if connection timeout
clientPeer.on('timeout', signal);
return client;
};
Eureca.Transport.register('webrtc', '', createClient, createServer);
})(WebRTCTransport = Transports.WebRTCTransport || (Transports.WebRTCTransport = {}));
})(Transports = Eureca.Transports || (Eureca.Transports = {}));
})(Eureca || (Eureca = {}));
/** @ignore */
var Eureca;
(function (Eureca) {
var Protocol = (function () {
function Protocol() {
}
//internal stuff
Protocol.contractId = '__eureca__';
Protocol.authReq = '__auth__';
Protocol.authResp = '__authr__';
Protocol.signal = '__signal__';
Protocol.signalACK = '__sigack__';
//RPC stuff
Protocol.functionId = 'f';
Protocol.argsId = 'a';
Protocol.resultId = 'r';
Protocol.errorId = 'e';
Protocol.signatureId = 's';
Protocol.context = 'c';
return Protocol;
})();
Eureca.Protocol = Protocol;
})(Eureca || (Eureca = {}));
/// <reference path="Protocol.config.ts" />
/// <reference path="Util.class.ts" />
/** @ignore */
var Eureca;
(function (Eureca) {
// Class
var Stub = (function () {
// Constructor
function Stub(settings) {
if (settings === void 0) { settings = {}; }
this.settings = settings;
//this.callbacks = {};
}
Stub.registerCallBack = function (sig, cb) {
this.callbacks[sig] = cb;
};
Stub.doCallBack = function (sig, result, error) {
if (!sig)
return;
var proxyObj = this.callbacks[sig];
delete this.callbacks[sig];
if (proxyObj !== undefined) {
proxyObj.status = 1;
proxyObj.result = result;
proxyObj.error = error;
if (error == null)
proxyObj.callback(result);
else
proxyObj.errorCallback(error);
}
};
//invoke remote function by creating a proxyObject and sending function name and arguments to the remote side
Stub.prototype.invokeRemote = function (context, fname, socket) {
var args = [];
for (var _i = 3; _i < arguments.length; _i++) {
args[_i - 3] = arguments[_i];
}
var proxyObj = {
status: 0,
result: null,
error: null,
sig: null,
callback: function () { },
errorCallback: function () { },
//TODO : use the standardized promise syntax instead of onReady
then: function (fn, errorFn) {
if (this.status != 0) {
if (this.error == null)
fn(this.result);
else
errorFn(this.error);
return;
}
if (typeof fn == 'function') {
this.callback = fn;
}
if (typeof errorFn == 'function') {
this.errorCallback = errorFn;
}
}
};
//onReady retro-compatibility with older eureca.io versions
proxyObj['onReady'] = proxyObj.then;
var RMIObj = {};
var argsArray = args; //Array.prototype.slice.call(arguments, 0);
var uid = Eureca.Util.randomStr();
proxyObj.sig = uid;
Stub.registerCallBack(uid, proxyObj);
RMIObj[Eureca.Protocol.functionId] = fname;
RMIObj[Eureca.Protocol.signatureId] = uid;
if (argsArray.length > 0)
RMIObj[Eureca.Protocol.argsId] = argsArray;
socket.send(this.settings.serialize.call(context, RMIObj));
return proxyObj;
};
/**
* Generate proxy functions allowing to call remote functions
*/
Stub.prototype.importRemoteFunction = function (handle, socket, functions /*, serialize=null*/) {
var _this = this;
if (functions === undefined)
return;
for (var i = 0; i < functions.length; i++) {
(function (idx, fname) {
var proxy = handle;
/* namespace parsing */
var ftokens = fname.split('.');
for (var i = 0; i < ftokens.length - 1; i++) {
proxy[ftokens[i]] = proxy[ftokens[i]] || {};
proxy = proxy[ftokens[i]];
}
var _fname = ftokens[ftokens.length - 1];
/* end namespace parsing */
//TODO : do we need to re generate proxy function if it's already declared ?
proxy[_fname] = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i - 0] = arguments[_i];
}
args.unshift(socket);
args.unshift(fname);
args.unshift(proxy[_fname]);
return _this.invokeRemote.apply(_this, args);
/*
var proxyObj = {
status: 0,
result: null,
error: null,
sig:null,
callback: function () { },
errorCallback: function () { },
//TODO : use the standardized promise syntax instead of onReady
then: function (fn, errorFn) {
if (this.status != 0) {
if (this.error == null)
fn(this.result);
else
errorFn(this.error);
return;
}
if (typeof fn == 'function') {
this.callback = fn;
}
if (typeof errorFn == 'function') {
this.errorCallback = errorFn;
}
}
}
//onReady retro-compatibility with older eureca.io versions
proxyObj['onReady'] = proxyObj.then;
var RMIObj: any = {};
var argsArray = args;//Array.prototype.slice.call(arguments, 0);
var uid = Eureca.Util.randomStr();
proxyObj.sig = uid;
Stub.registerCallBack(uid, proxyObj);
RMIObj[Protocol.functionId] = _this.settings.useIndexes ? idx : fname;
RMIObj[Protocol.signatureId] = uid;
if (argsArray.length > 0) RMIObj[Protocol.argsId] = argsArray;
//Experimental custom context sharing
//allow sharing global context (set in serverProxy/clientProxy) or local proxy set in the caller object
//if (proxy[_fname].context || handle.context) RMIObj[Protocol.context] = proxy[_fname].context || handle.context;
//socket.send(JSON.stringify(RMIObj));
socket.send(_this.settings.serialize.call(proxyObj, RMIObj));
return proxyObj;
*/
};
})(i, functions[i]);
}
};
Stub.prototype.sendResult = function (socket, sig, result, error) {
if (!socket)
return;
var retObj = {};
retObj[Eureca.Protocol.signatureId] = sig;
retObj[Eureca.Protocol.resultId] = result;
retObj[Eureca.Protocol.errorId] = error;
socket.send(JSON.stringify(retObj));
};
//invoke exported function and send back the result to the invoker
Stub.prototype.invoke = function (context, handle, obj, socket) {
var fId = parseInt(obj[Eureca.Protocol.functionId]);
var fname = isNaN(fId) ? obj[Eureca.Protocol.functionId] : handle.contract[fId];
/* browing namespace */
var ftokens = fname.split('.');
var func = handle.exports;
for (var i = 0; i < ftokens.length; i++) {
if (!func) {
console.log('Invoke error', obj[Eureca.Protocol.functionId] + ' is not a function', '');
this.sendResult(socket, obj[Eureca.Protocol.signatureId], null, 'Invoke error : ' + obj[Eureca.Protocol.functionId] + ' is not a function');
return;
}
func = func[ftokens[i]];
}
/* ***************** */
//var func = this.exports[fname];
if (typeof func != 'function') {
//socket.send('Invoke error');
console.log('Invoke error', obj[Eureca.Protocol.functionId] + ' is not a function', '');
this.sendResult(socket, obj[Eureca.Protocol.signatureId], null, 'Invoke error : ' + obj[Eureca.Protocol.functionId] + ' is not a function');
return;
}
//obj.a.push(conn); //add connection object to arguments
try {
obj[Eureca.Protocol.argsId] = obj[Eureca.Protocol.argsId] || [];
var result = func.apply(context, obj[Eureca.Protocol.argsId]);
//console.log('sending back result ', result, obj)
if (socket && obj[Eureca.Protocol.signatureId] && !context.async) {
this.sendResult(socket, obj[Eureca.Protocol.signatureId], result, null);
}
obj[Eureca.Protocol.argsId].unshift(socket);
if (typeof func.onCall == 'function')
func.onCall.apply(context, obj[Eureca.Protocol.argsId]);
}
catch (ex) {
console.log('EURECA Invoke exception!! ', ex.stack);
}
};
Stub.callbacks = {};
return Stub;
})();
Eureca.Stub = Stub;
})(Eureca || (Eureca = {}));
/** @ignore */
var Eureca;
(function (Eureca) {
var Contract = (function () {
// Constructor
function Contract() {
}
//Removing need for Harmony proxies for simplification
//static handlerMaker(obj, contract) {
// return {
// getOwnPropertyDescriptor: function (name) {
// var desc = Object.getOwnPropertyDescriptor(obj, name);
// // a trapping proxy's properties must always be configurable
// if (desc !== undefined) { desc.configurable = true; }
// return desc;
// },
// getPropertyDescriptor: function (name) {
// var desc = (<any>Object).getPropertyDescriptor(obj, name); // not in ES5
// // a trapping proxy's properties must always be configurable
// if (desc !== undefined) { desc.configurable = true; }
// return desc;
// },
// getOwnPropertyNames: function () {
// return Object.getOwnPropertyNames(obj);
// },
// getPropertyNames: function () {
// return (<any>Object).getPropertyNames(obj); // not in ES5
// },
// defineProperty: function (name, desc) {
// Object.defineProperty(obj, name, desc);
// },
// delete: function (name) { return delete obj[name]; },
// fix: function () {
// if (Object.isFrozen(obj)) {
// var result = {};
// Object.getOwnPropertyNames(obj).forEach(function (name) {
// result[name] = Object.getOwnPropertyDescriptor(obj, name);
// });
// return result;
// }
// // As long as obj is not frozen, the proxy won't allow itself to be fixed
// return undefined; // will cause a TypeError to be thrown
// },
// has: function (name) { return name in obj; },
// hasOwn: function (name) { return ({}).hasOwnProperty.call(obj, name); },
// get: function (receiver, name) { return obj[name]; },
// set: function (receiver, name, val) {
// console.log(' Contract +=', name);
// contract.push(name);
// obj[name] = val;
// return true;
// }, // bad behavior when set fails in non-strict mode
// enumerate: function () {
// var result = [];
// for (var name in obj) { result.push(name); };
// return result;
// },
// keys: function () { return Object.keys(obj); }
// };
//}
//Removing need for Harmony proxies for simplification
//static proxify(target, contract): any {
// if (typeof Proxy == 'undefined') return target;
// //ELog.log('I', 'Harmony proxy', 'Enabled');
// return Proxy.create((<any>Contract).handlerMaker(target, contract));
//}
Contract.parseNS = function (target, ns, parent) {
if (ns === void 0) { ns = []; }
if (parent === void 0) { parent = ''; }
for (var prop in target) {
//console.log('parsing prop', parent+prop, typeof target[prop]);
if (typeof target[prop] == 'function') {
ns.push(parent + prop);
}
else {
//FIXME : will crash if sub NS has no children : example : exports.id = 'hello'
Contract.parseNS(target[prop], ns, parent + prop + '.');
}
}
return ns;
};
Contract.ensureContract = function (target, contract) {
var contract = this.parseNS(target);
//console.log('ns = ', contract);
/*
if (typeof Proxy == 'undefined') {
contract = [];
for (var prop in target) {
contract.push(prop);
}
}
*/
return contract;
};
return Contract;
})();
Eureca.Contract = Contract;
})(Eureca || (Eureca = {}));
if (typeof exports != 'undefined')
exports.Eureca = Eureca;
/// <reference path="transport/Primus.transport.ts" />
/// <reference path="transport/WebRTC.transport.ts" />
/// <reference path="Transport.ts" />
/// <reference path="Stub.ts" />
/// <reference path="EObject.class.ts" />
/// <reference path="Contract.class.ts" />
var fs = require('fs');
//var EProxy = require('./EurecaProxy.class.js').Eureca.EurecaProxy;
//var io = require('engine.io');
var util = require('util');
var host = '';
function getUrl(req) {
var scheme = req.headers.referer !== undefined ? req.headers.referer.split(':')[0] : 'http';
host = scheme + '://' + req.headers.host;
return host;
}
var hproxywarn = false;
var clientUrl = {};
var ELog = console;
var Eureca;
(function (Eureca) {
/**
* Eureca server constructor
* This constructor takes an optional settings object
* @constructor Server
* @param {object} [settings] - have the following properties
* @property {string} [settings.transport=engine.io] - can be "engine.io", "sockjs", "websockets", "faye" or "browserchannel" by default "engine.io" is used
* @property {function} [settings.authenticate] - If this function is defined, the client will not be able to invoke server functions until it successfully call the client side authenticate method, which will invoke this function.
* @property {function} [settings.serialize] - If defined, this function is used to serialize the request object before sending it to the client (default is JSON.stringify). This function can be useful to add custom information/meta-data to the transmitted request.
* @property {function} [settings.deserialize] - If defined, this function is used to deserialize the received response string.
* @example
* <h4> # default instantiation</h4>
* var Eureca = require('eureca.io');
* //use default transport
* var server = new Eureca.Server();
*
*
* @example
* <h4> # custom transport instantiation </h4>
* var Eureca = require('eureca.io');
* //use websockets transport
* var server = new Eureca.Server({transport:'websockets'});
*
* @example
* <h4> # Authentication </h4>
* var Eureca = require('eureca.io');
*
* var eurecaServer = new Eureca.Server({
* authenticate: function (authToken, next) {
* console.log('Called Auth with token=', authToken);
*
* if (isValidToekn(authToken)) next(); // authentication success
* else next('Auth failed'); //authentication fail
* }
* });
*
* @see attach
* @see getClient
*
*
*/
var Server = (function (_super) {
__extends(Server, _super);
function Server(settings) {
if (settings === void 0) { settings = {}; }
_super.call(this);
this.settings = settings;
this.scriptCache = '';
this.serialize = JSON.stringify;
this.deserialize = function (message) {
var jobj;
if (typeof message != 'object') {
try {
jobj = JSON.parse(message);
}
catch (ex) { }
;
}
else {
jobj = message;
}
return jobj;
};
if (typeof settings.serialize == 'function')
this.serialize = settings.serialize;
else
settings.serialize = this.serialize;
if (typeof settings.deserialize == 'function')
this.deserialize = settings.deserialize;
else
settings.deserialize = this.deserialize;
this.stub = new Eureca.Stub(settings);
settings.transformer = settings.transport || 'engine.io';
this.transport = Eureca.Transport.get(settings.transformer);
this.contract = [];
this.debuglevel = settings.debuglevel || 1;
//Removing need for Harmony proxies for simplification
//var _exports = {};
//this.exports = Contract.proxify(_exports, this.contract);
this.exports = {};
this.allowedF = [];
this.clients = {};
this.useAuthentication = (typeof this.settings.authenticate == 'function');
if (this.useAuthentication)
this.exports.authenticate = this.settings.authenticate;
//this.registerEvents(['onConnect', 'onDisconnect', 'onMessage', 'onError']);
}
Server.prototype.onConnect = function (callback) {
this.on('connect', callback);
};
Server.prototype.onDisconnect = function (callback) {
this.on('disconnect', callback);
};
Server.prototype.onMessage = function (callback) {
this.on('message', callback);
};
Server.prototype.onError = function (callback) {
this.on('error', callback);
};
/**
* This method is used to get the client proxy of a given connection.
* it allows the server to call remote client function
*
* @function Server#getClient
* @param {String} id - client identifier
* @returns {Proxy}
*
* @example
* //we suppose here that the clients are exposing hello() function
* //onConnect event give the server an access to the client socket
* server.onConnect(function (socket) {
* //get client proxy by socket ID
* var client = server.getClient(socket.id);
* //call remote hello() function.
* client.hello();
* }
*/
Server.prototype.getClient = function (id) {
var conn = this.clients[id];
if (conn === undefined)
return false;
if (conn.clientProxy !== undefined)
return conn.clientProxy;
conn.clientProxy = {};
conn._proxy = conn.clientProxy;
//this.importClientFunction(conn.client, conn, this.allowedF);
this.stub.importRemoteFunction(conn.clientProxy, conn, conn.contract || this.allowedF /*, this.serialize*/);
return conn.clientProxy;
};
/**
* **!! Experimental !! **<br />
* force regeneration of client remote function signatures
* this is needed if for some reason we need to dynamically update allowed client functions at runtime
* @function Server#updateClientAllowedFunctions
* @param {String} id - client identifier
*/
Server.prototype.updateClientAllowedFunctions = function (id) {
var conn = this.clients[id];
if (conn === undefined)
return false;
conn.clientProxy = {};
conn._proxy = conn.clientProxy;
//this.importClientFunction(conn.client, conn, this.allowedF);
this.stub.importRemoteFunction(conn.clientProxy, conn, this.allowedF /*, this.serialize*/);
};
Server.prototype.getConnection = function (id) {
return this.clients[id];
};
Server.prototype.sendScript = function (request, response, prefix) {
if (this.scriptCache != '') {
response.writeHead(200);
response.write(this.scriptCache);
response.end();
return;
}
this.scriptCache = '';
if (this.transport.script && this.transport.script != '')
this.scriptCache += fs.readFileSync(__dirname + this.transport.script);
this.scriptCache += '\nvar _eureca_prefix = "' + prefix + '";\n';
this.scriptCache += '\nvar _eureca_uri = "' + getUrl(request) + '";\n';
this.scriptCache += '\nvar _eureca_host = "' + getUrl(request) + '";\n';
//FIXME : override primus hardcoded pathname
this.scriptCache += '\nif (typeof Primus != "undefined") Primus.prototype.pathname = "/' + prefix + '";\n';
this.scriptCache += fs.readFileSync(__dirname + '/EurecaClient.js');
response.writeHead(200);
response.write(this.scriptCache);
response.end();
};
/**
* **!! Experimental !! **<br />
* Sends exported server functions to all connected clients <br />
* This can be used if the server is designed to dynamically expose new methods.
*
* @function Server#updateContract
*/
Server.prototype.updateContract = function () {
this.contract = Eureca.Contract.ensureContract(this.exports, this.contract);
for (var id in this.clients) {
var socket = this.clients[id];
var sendObj = {};
sendObj[Eureca.Protocol.contractId] = this.contract;
socket.send(JSON.stringify(sendObj));
}
};
//this function is internally used to return value for asynchronous calls in the server side
Server.returnFunc = function (result, error) {
if (error === void 0) { error = null; }
var retObj = {};
retObj[Eureca.Protocol.signatureId] = this['retId'];
retObj[Eureca.Protocol.resultId] = result;
retObj[Eureca.Protocol.errorId] = error;
this['connection'].send(JSON.stringify(retObj));
};
Server.prototype._handleServer = function (ioServer) {
var _this = this;
//ioServer.on('connection', function (socket) {
ioServer.onconnect(function (socket) {
//socket.siggg = 'A';
socket.eureca.remoteAddress = socket.remoteAddress;
_this.clients[socket.id] = socket;
//Send EURECA contract
var sendContract = function () {
_this.contract = Eureca.Contract.ensureContract(_this.exports, _this.contract);
var sendObj = {};
sendObj[Eureca.Protocol.contractId] = _this.contract;
if (_this.allowedF == 'all')
sendObj[Eureca.Protocol.signatureId] = socket.id;
socket.send(JSON.stringify(sendObj));
};
if (!_this.useAuthentication)
sendContract();
//attach socket client
socket.clientProxy = _this.getClient(socket.id);
socket._proxy = socket.clientProxy;
/**
* Triggered each time a new client is connected
*
* @event Server#connect
* @property {ISocket} socket - client socket.
*/
_this.trigger('connect', socket);
socket.on('message', function (message) {
/**
* Triggered each time a new message is received from a client.
*
* @event Server#message
* @property {String} message - the received message.
* @property {ISocket} socket - client socket.
*/
_this.trigger('message', message, socket);
var context;
var jobj = _this.deserialize.call(socket, message);
//if (typeof message != 'object') {
// try {
// jobj = JSON.parse(message);
// } catch (ex) { };
//}
//else {
// jobj = message;
//}
if (jobj === undefined) {
_this.trigger('unhandledMessage', message, socket);
return;
}
//Handle authentication
if (jobj[Eureca.Protocol.authReq] !== undefined) {
if (typeof _this.settings.authenticate == 'function') {
var args = jobj[Eureca.Protocol.authReq];
args.push(function (error) {
if (error == null) {
socket.eureca.authenticated = true;
sendContract();
}
var authResponse = {};
authResponse[Eureca.Protocol.authResp] = [error];
socket.send(authResponse);
_this.trigger('authentication', error);
});
var context = {
user: { clientId: socket.id },
connection: socket,
socket: socket,
};
_this.settings.authenticate.apply(context, args);
}
return;
}
if (_this.useAuthentication && !socket.eureca.authenticated) {
console.log('Authentication needed for ', socket.id);
return;
}
/** Experimental : dynamic client contract*/
//if (jobj[Eureca.Protocol.contractId] !== undefined) {
// socket.contract = jobj[Eureca.Protocol.contractId];
// return;
//}
/*****************************************/
//handle remote call
if (jobj[Eureca.Protocol.functionId] !== undefined) {
// if (socket.context == undefined) {
// var returnFunc = function (result, error=null) {
// var retObj = {};
// retObj[Eureca.Protocol.signatureId] = this.retId;
// retObj[Eureca.Protocol.resultId] = result;
//retObj[Eureca.Protocol.errorId] = error;
// this.connection.send(JSON.stringify(retObj));
// }
// socket.context = { user: { clientId: socket.id }, connection: socket, socket: socket, clientProxy:socket.clientProxy, async: false, retId: jobj[Eureca.Protocol.signatureId], 'return': returnFunc };
// }
// socket.context.retId = jobj[Eureca.Protocol.signatureId];
// _this.stub.invoke(socket.context, _this, jobj, socket);
var context = {
user: { clientId: socket.id },
connection: socket,
socket: socket,
clientProxy: socket.clientProxy,
async: false,
retId: jobj[Eureca.Protocol.signatureId],
return: Server.returnFunc
};
//context.retId = jobj[Eureca.Protocol.signatureId];
//if (!_this.settings.preInvoke || jobj[Eureca.Protocol.functionId] == 'authenticate' || (typeof _this.settings.preInvoke == 'function' && _this.settings.preInvoke.apply(context)))
//Experimental custom context sharing
//remote context is shared throught serverProxy or proxy function in the client side
//if (jobj[Eureca.Protocol.context]) {
// socket.remoteContext = jobj[Eureca.Protocol.context];
//}
_this.stub.invoke(context, _this, jobj, socket);
return;
}
//handle remote response
if (jobj[Eureca.Protocol.signatureId] !== undefined) {
//_this.stub.doCallBack(jobj[Eureca.Protocol.signatureId], jobj[Eureca.Protocol.resultId], jobj[Eureca.Protocol.errorId]);
Eureca.Stub.doCallBack(jobj[Eureca.Protocol.signatureId], jobj[Eureca.Protocol.resultId], jobj[Eureca.Protocol.errorId]);
return;
}
_this.trigger('unhandledMessage', message, socket);
});
socket.on('error', function (e) {
/**
* triggered if an error occure.
*
* @event Server#error
* @property {String} error - the error message
* @property {ISocket} socket - client socket.
*/
_this.trigger('error', e, socket);
});
socket.on('close', function () {
/**
* triggered when the client is disconneced.
*
* @event Server#disconnect
* @property {ISocket} socket - client socket.
*/
//console.log('disconnected deletting ', _this.clients);
_this.trigger('disconnect', socket);
delete _this.clients[socket.id];
//console.log('disconnected ', _this.clients);
//console.log('i', '#of clients changed ', EURECA.clients.length, );
});
});
};
//Removing need for Harmony proxies for simplification
//private _checkHarmonyProxies()
//{
// if (typeof Proxy == 'undefined' && !hproxywarn) {
// ELog.log('I', 'Harmony proxy not found', 'using workaround');
// ELog.log('I', 'to avoid this message please use : node --harmony-proxies <app>', '');
// hproxywarn = true;
// }
//}
/**
* Sends exported server functions to all connected clients <br />
* This can be used if the server is designed to dynamically expose new methods.
*
* @function attach
* @memberof Server#
* @param {Server} - a nodejs {@link https://nodejs.org/api/http.html#http_class_http_server|nodejs http server}
* or {@link http://expressjs.com/api.html#application|expressjs Application}
*
*/
Server.prototype.attach = function (server) {
var app = server;
if (server._events && server._events.request !== undefined && server.routes === undefined && server._events.request.on)
app = server._events.request;
//this._checkHarmonyProxies();
this.allowedF = this.settings.allow || [];
var _prefix = this.settings.prefix || 'eureca.io';
var _clientUrl = this.settings.clientScript || '/eureca.js';
var _transformer = this.settings.transformer;
var _parser = this.settings.parser;
//initialising server
//var ioServer = io.attach(server, { path: '/'+_prefix });
this.ioServer = this.transport.createServer(server, { prefix: _prefix, transformer: _transformer, parser: _parser });
//console.log('Primus ? ', ioServer.primus);
//var scriptLib = (typeof ioServer.primus == 'function') ? ioServer.primus.library() : null;
var _this = this;
this._handleServer(this.ioServer);
//install on express
//sockjs_server.installHandlers(server, {prefix:_prefix});
if (app.get && app.post) {
app.get(_clientUrl, function (request, response) {
_this.sendScript(request, response, _prefix);
});
}
else {
app.on('request', function (request, response) {
if (request.method === 'GET') {
if (request.url.split('?')[0] === _clientUrl) {
_this.sendScript(request, response, _prefix);
}
}
});
}
//console.log('>>>>>>>>>>>> ', app.get);
//Workaround : nodejs 0.10.0 have a strange behaviour making remoteAddress unavailable when connecting from a nodejs client
server.on('request', function (request, response) {
if (!request.query)
return;
var id = request.query.sid;
var client = _this.clients[request.query.sid];
if (client) {
client.eureca = client.eureca || {};
client.eureca.remoteAddress = client.eureca.remoteAddress || request.socket.remoteAddress;
client.eureca.remotePort = client.eureca.remotePort || request.socket.remotePort;
}
//req.eureca = {
// remoteAddress: req.socket.remoteAddress,
// remotePort: req.socket.remotePort
//}
});
};
return Server;
})(Eureca.EObject);
Eureca.Server = Server;
})(Eureca || (Eureca = {}));
exports.Eureca = Eureca;