UNPKG

eureca.io

Version:

Nodejs transparent bidirectional remote procedure call (RPC) supporting multiple transports : WebRTC, Websocket, engine.io, faye ...etc

223 lines (183 loc) 7.17 kB
/// <reference path="../EObject.class.ts" /> /// <reference path="../Util.class.ts" /> /// <reference path="../Transport.ts" /> /// <reference path="../IServer.interface.ts" /> /// <reference path="../ISocket.interface.ts" /> /** @ignore */ declare var __dirname; /** @ignore */ declare var process; /** @ignore */ declare var require; /** @ignore */ declare var Primus: any; /** @ignore */ module Eureca.Transports.PrimusTransport { if (Eureca.Util.isNodejs) { Primus = require('primus'); } export class Socket extends EObject implements ISocket { public request; public id; public remoteAddress; public eureca:any = {}; //public webRTCChannel:any; //private wRTCPeer; constructor(public socket?: any) { super(); 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(); } private bindEvents() { 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); // }); //} isAuthenticated(): boolean { return this.eureca.authenticated; } send(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); } } close() { if (this.socket.end) { this.socket.end(); } else { this.socket.close(); } } //deprecated ? onopen(callback: (any?) => void) { this.socket.on('open', callback); } onmessage(callback: (any?) => void) { this.socket.on('data', callback); } onclose(callback: (any?) => void) { this.socket.on('end', callback); } onerror(callback: (any?) => void) { this.socket.on('error', callback); } ondisconnect(callback: (any?) => void) { this.socket.on('reconnecting', callback); } } export class Server implements IServer { constructor(public primus: any) { } //on client connect onconnect(callback: (Socket) => void) { this.primus.on('connection', function (psocket) { var socket = new Socket(psocket) //Eureca.Util.extend(iosocket, socket); callback(socket); }); } } var createServer = function (hook, options: any = {}) { try { //var primusOptions: any = {}; options.pathname = options.prefix ? '/' + options.prefix : undefined; var primus = new Primus(hook, options); // // sync middleware // primus.use('eureca', function (req, res) { // console.log('EURECA middleware in action'); // req.tag='eureca.io'; // console.log('>> req.tag=',req.tag); // console.log('>> req=',req.headers.cookie); // }); //primus.save(__dirname + '/js/primus.js'); var primusTransport = Transport.get('primus'); //populate the client script primusTransport.script = primus.library(); 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: any = {}) { 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; } //Transport.register('primus', '/js/primus.js', createClient, createServer); //set empty client script by default, it'll be populated by createClient function Transport.register( 'primus', '', createClient, createServer, (v)=>v, (v)=>v ); }