You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1428 lines
53 KiB
JavaScript
1428 lines
53 KiB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
|
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
module.exports = factory();
|
|
else if(typeof define === 'function' && define.amd)
|
|
define([], factory);
|
|
else if(typeof exports === 'object')
|
|
exports["nf"] = factory();
|
|
else
|
|
root["nf"] = factory();
|
|
})(this, function() {
|
|
return /******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
|
|
/******/ // Check if module is in cache
|
|
/******/ if(installedModules[moduleId])
|
|
/******/ return installedModules[moduleId].exports;
|
|
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ exports: {},
|
|
/******/ id: moduleId,
|
|
/******/ loaded: false
|
|
/******/ };
|
|
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.loaded = true;
|
|
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
|
|
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "";
|
|
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(0);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
var _Facade = __webpack_require__(1);
|
|
|
|
var _Facade2 = _interopRequireDefault(_Facade);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
module.exports = new _Facade2.default();
|
|
|
|
/***/ },
|
|
/* 1 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _WebChannel = __webpack_require__(2);
|
|
|
|
var _WebChannel2 = _interopRequireDefault(_WebChannel);
|
|
|
|
var _ServiceProvider = __webpack_require__(4);
|
|
|
|
var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var Facade = function () {
|
|
function Facade() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, Facade);
|
|
|
|
this.defaults = {
|
|
webrtc: {}
|
|
};
|
|
this.settings = Object.assign({}, this.defaults, options);
|
|
}
|
|
|
|
_createClass(Facade, [{
|
|
key: 'create',
|
|
value: function create() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
return new _WebChannel2.default();
|
|
}
|
|
}, {
|
|
key: 'join',
|
|
value: function join(key) {
|
|
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
var defaults = {
|
|
connector: 'WebRTCService',
|
|
protocol: 'ExchangeProtocolService'
|
|
};
|
|
var settings = Object.assign({}, defaults, options);
|
|
var connector = _ServiceProvider2.default.get(settings.connector);
|
|
var protocol = _ServiceProvider2.default.get(settings.protocol);
|
|
var connectorOptions = { signaling: settings.signaling, facade: this };
|
|
return new Promise(function (resolve, reject) {
|
|
connector.join(key, connectorOptions).then(function (channel) {
|
|
var webChannel = new _WebChannel2.default(options);
|
|
channel.webChannel = webChannel;
|
|
channel.onmessage = protocol.onmessage;
|
|
webChannel.channels.add(channel);
|
|
webChannel.onopen = function () {
|
|
resolve(webChannel);
|
|
};
|
|
}, reject);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'invite',
|
|
value: function invite() {
|
|
// TODO
|
|
}
|
|
}, {
|
|
key: '_onJoining',
|
|
value: function _onJoining() {
|
|
// TODO
|
|
}
|
|
}, {
|
|
key: '_onLeaving',
|
|
value: function _onLeaving() {
|
|
// TODO
|
|
}
|
|
}, {
|
|
key: '_onMessage',
|
|
value: function _onMessage() {
|
|
// TODO
|
|
}
|
|
}, {
|
|
key: '_onPeerMessage',
|
|
value: function _onPeerMessage() {
|
|
// TODO
|
|
}
|
|
}, {
|
|
key: '_onInvite',
|
|
value: function _onInvite() {
|
|
// TODO
|
|
}
|
|
}]);
|
|
|
|
return Facade;
|
|
}();
|
|
|
|
exports.default = Facade;
|
|
|
|
/***/ },
|
|
/* 2 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _constants = __webpack_require__(3);
|
|
|
|
var cs = _interopRequireWildcard(_constants);
|
|
|
|
var _ServiceProvider = __webpack_require__(4);
|
|
|
|
var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var WebChannel = function () {
|
|
function WebChannel() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, WebChannel);
|
|
|
|
this.defaults = {
|
|
connector: cs.WEBRTC_SERVICE,
|
|
topology: cs.FULLYCONNECTED_SERVICE,
|
|
protocol: cs.EXCHANGEPROTOCOL_SERVICE
|
|
};
|
|
this.settings = Object.assign({}, this.defaults, options);
|
|
|
|
// Private attributes
|
|
this.protocol = cs.EXCHANGEPROTOCOL_SERVICE;
|
|
|
|
// Public attributes
|
|
this.id;
|
|
this.myID = this._generateID();
|
|
this.channels = new Set();
|
|
this.onjoining;
|
|
this.onleaving;
|
|
this.onmessage;
|
|
}
|
|
|
|
_createClass(WebChannel, [{
|
|
key: 'leave',
|
|
value: function leave() {}
|
|
}, {
|
|
key: 'send',
|
|
value: function send(data) {
|
|
var channel = this;
|
|
return new Promise(function (resolve, reject) {
|
|
if (channel.channels.size === 0) {
|
|
resolve();
|
|
}
|
|
var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
|
|
channel.topologyService.broadcast(channel, protocol.message(cs.USER_DATA, { id: channel.myID, data: data })).then(resolve, reject);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'sendPing',
|
|
value: function sendPing() {
|
|
var channel = this;
|
|
return new Promise(function (resolve, reject) {
|
|
if (channel.channels.size === 0) {
|
|
resolve();
|
|
}
|
|
var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
|
|
channel.topologyService.broadcast(channel, protocol.message(cs.PING, { data: '' })).then(resolve, reject);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'getHistory',
|
|
value: function getHistory(historyKeeperID) {
|
|
var channel = this;
|
|
return new Promise(function (resolve, reject) {
|
|
var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
|
|
channel.topologyService.sendTo(historyKeeperID, channel, protocol.message(cs.GET_HISTORY, { id: channel.myID, data: '' })).then(resolve, reject);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'sendTo',
|
|
value: function sendTo(fromId, toId, msg) {
|
|
var channel = this;
|
|
return new Promise(function (resolve, reject) {
|
|
var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
|
|
channel.topologyService.sendTo(toId, channel, protocol.message(cs.USER_DATA, { id: fromId, data: msg })).then(resolve, reject);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'openForJoining',
|
|
value: function openForJoining() {
|
|
var _this = this;
|
|
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
var settings = Object.assign({}, this.settings, options);
|
|
var connector = _ServiceProvider2.default.get(settings.connector);
|
|
return connector.open(function (channel) {
|
|
// 1) New dataChannel connection established.
|
|
// NEXT: add it to the network
|
|
var protocol = _ServiceProvider2.default.get(_this.protocol);
|
|
_this.topologyService = _ServiceProvider2.default.get(_this.settings.topology);
|
|
channel.webChannel = _this;
|
|
channel.onmessage = protocol.onmessage;
|
|
|
|
// 2.1) Send to the new client the webChannel topology name
|
|
channel.send(protocol.message(cs.JOIN_START, _this.settings.topology));
|
|
|
|
// 2.2) Ask to topology to add the new client to this webChannel
|
|
_this.topologyService.addStart(channel, _this).then(function (id) {
|
|
_this.topologyService.broadcast(_this, protocol.message(cs.JOIN_FINISH, id));
|
|
_this.onJoining(id);
|
|
});
|
|
}, settings).then(function (data) {
|
|
return data;
|
|
});
|
|
}
|
|
}, {
|
|
key: 'closeForJoining',
|
|
value: function closeForJoining() {}
|
|
}, {
|
|
key: 'isInviting',
|
|
value: function isInviting() {}
|
|
}, {
|
|
key: '_generateID',
|
|
value: function _generateID() {
|
|
var MIN_LENGTH = 10;
|
|
var DELTA_LENGTH = 10;
|
|
var MASK = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
var result = '';
|
|
var length = MIN_LENGTH + Math.round(Math.random() * DELTA_LENGTH);
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
result += MASK[Math.round(Math.random() * (MASK.length - 1))];
|
|
}
|
|
return result;
|
|
}
|
|
}, {
|
|
key: 'topology',
|
|
set: function set(topologyServiceName) {
|
|
this.settings.topology = topologyServiceName;
|
|
this.topologyService = _ServiceProvider2.default.get(topologyServiceName);
|
|
},
|
|
get: function get() {
|
|
return this.settigns.topology;
|
|
}
|
|
}]);
|
|
|
|
return WebChannel;
|
|
}();
|
|
|
|
exports.default = WebChannel;
|
|
|
|
/***/ },
|
|
/* 3 */
|
|
/***/ function(module, exports) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
// API user's message
|
|
var USER_DATA = exports.USER_DATA = 0;
|
|
var GET_HISTORY = exports.GET_HISTORY = 6;
|
|
|
|
// Internal messages
|
|
var JOIN_START = exports.JOIN_START = 2;
|
|
var JOIN_FINISH = exports.JOIN_FINISH = 4;
|
|
var YOUR_NEW_ID = exports.YOUR_NEW_ID = 5;
|
|
var PING = exports.PING = 7;
|
|
|
|
// Internal message to a specific Service
|
|
var SERVICE_DATA = exports.SERVICE_DATA = 3;
|
|
|
|
var WEBRTC_SERVICE = exports.WEBRTC_SERVICE = 'WebRTCService';
|
|
var WEBSOCKET_SERVICE = exports.WEBSOCKET_SERVICE = 'WebSocketService';
|
|
var FULLYCONNECTED_SERVICE = exports.FULLYCONNECTED_SERVICE = 'FullyConnectedService';
|
|
var STAR_SERVICE = exports.STAR_SERVICE = 'StarTopologyService';
|
|
var EXCHANGEPROTOCOL_SERVICE = exports.EXCHANGEPROTOCOL_SERVICE = 'ExchangeProtocolService';
|
|
var WSPROTOCOL_SERVICE = exports.WSPROTOCOL_SERVICE = 'WebSocketProtocolService';
|
|
|
|
/***/ },
|
|
/* 4 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _constants = __webpack_require__(3);
|
|
|
|
var cs = _interopRequireWildcard(_constants);
|
|
|
|
var _FullyConnectedService = __webpack_require__(5);
|
|
|
|
var _FullyConnectedService2 = _interopRequireDefault(_FullyConnectedService);
|
|
|
|
var _StarTopologyService = __webpack_require__(6);
|
|
|
|
var _StarTopologyService2 = _interopRequireDefault(_StarTopologyService);
|
|
|
|
var _WebRTCService = __webpack_require__(7);
|
|
|
|
var _WebRTCService2 = _interopRequireDefault(_WebRTCService);
|
|
|
|
var _WebSocketService = __webpack_require__(8);
|
|
|
|
var _WebSocketService2 = _interopRequireDefault(_WebSocketService);
|
|
|
|
var _ExchangeProtocolService = __webpack_require__(9);
|
|
|
|
var _ExchangeProtocolService2 = _interopRequireDefault(_ExchangeProtocolService);
|
|
|
|
var _WebSocketProtocolService = __webpack_require__(10);
|
|
|
|
var _WebSocketProtocolService2 = _interopRequireDefault(_WebSocketProtocolService);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var services = new Map();
|
|
|
|
var ServiceProvider = function () {
|
|
function ServiceProvider() {
|
|
_classCallCheck(this, ServiceProvider);
|
|
}
|
|
|
|
_createClass(ServiceProvider, null, [{
|
|
key: 'get',
|
|
value: function get(code) {
|
|
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
var service = undefined;
|
|
switch (code) {
|
|
case cs.WEBRTC_SERVICE:
|
|
service = new _WebRTCService2.default(options);
|
|
break;
|
|
case cs.WEBSOCKET_SERVICE:
|
|
service = new _WebSocketService2.default(options);
|
|
break;
|
|
case cs.FULLYCONNECTED_SERVICE:
|
|
service = new _FullyConnectedService2.default(options);
|
|
break;
|
|
case cs.STAR_SERVICE:
|
|
service = new _StarTopologyService2.default(options);
|
|
break;
|
|
case cs.EXCHANGEPROTOCOL_SERVICE:
|
|
service = new _ExchangeProtocolService2.default(options);
|
|
break;
|
|
case cs.WSPROTOCOL_SERVICE:
|
|
service = new _WebSocketProtocolService2.default(options);
|
|
break;
|
|
}
|
|
services.set(code, service);
|
|
return service;
|
|
}
|
|
}]);
|
|
|
|
return ServiceProvider;
|
|
}();
|
|
|
|
exports.default = ServiceProvider;
|
|
|
|
/***/ },
|
|
/* 5 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _constants = __webpack_require__(3);
|
|
|
|
var cs = _interopRequireWildcard(_constants);
|
|
|
|
var _ServiceProvider = __webpack_require__(4);
|
|
|
|
var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var FullyConnectedService = function () {
|
|
function FullyConnectedService() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, FullyConnectedService);
|
|
}
|
|
|
|
_createClass(FullyConnectedService, [{
|
|
key: 'addStart',
|
|
value: function addStart(channel, webChannel) {
|
|
var _this = this;
|
|
|
|
var protocol = _ServiceProvider2.default.get(cs.EXCHANGEPROTOCOL_SERVICE);
|
|
return new Promise(function (resolve, reject) {
|
|
channel.peerID = _this._generateID();
|
|
channel.send(protocol.message(cs.YOUR_NEW_ID, {
|
|
newID: channel.peerID,
|
|
myID: webChannel.myID
|
|
}));
|
|
if (Reflect.has(webChannel, 'aboutToJoin') && webChannel.aboutToJoin instanceof Map) {
|
|
webChannel.aboutToJoin.set(channel.peerID, channel);
|
|
} else {
|
|
webChannel.aboutToJoin = new Map();
|
|
}
|
|
|
|
if (webChannel.channels.size === 0) {
|
|
webChannel.channels.add(channel);
|
|
channel.onclose = function () {
|
|
webChannel.onLeaving(channel.peerID);
|
|
webChannel.channels.delete(channel);
|
|
};
|
|
resolve(channel.peerID);
|
|
} else {
|
|
(function () {
|
|
webChannel.successfullyConnected = new Map();
|
|
webChannel.successfullyConnected.set(channel.peerID, 0);
|
|
webChannel.connectionSucceed = function (id, withId) {
|
|
var counter = webChannel.successfullyConnected.get(withId);
|
|
webChannel.successfullyConnected.set(withId, ++counter);
|
|
if (webChannel.successfullyConnected.get(withId) === webChannel.channels.size) {
|
|
_this.addFinish(webChannel, withId);
|
|
resolve(withId);
|
|
}
|
|
};
|
|
var connector = _ServiceProvider2.default.get(cs.WEBRTC_SERVICE);
|
|
webChannel.channels.forEach(function (c) {
|
|
connector.connect(channel.peerID, webChannel, c.peerID);
|
|
});
|
|
})();
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: 'addFinish',
|
|
value: function addFinish(webChannel, id) {
|
|
if (id != webChannel.myID) {
|
|
(function () {
|
|
var channel = webChannel.aboutToJoin.get(id);
|
|
webChannel.channels.add(webChannel.aboutToJoin.get(id));
|
|
channel.onclose = function () {
|
|
webChannel.onLeaving(channel.peerID);
|
|
webChannel.channels.delete(channel);
|
|
};
|
|
//webChannel.aboutToJoin.delete(id)
|
|
if (Reflect.has(webChannel, 'successfullyConnected')) {
|
|
webChannel.successfullyConnected.delete(id);
|
|
}
|
|
})();
|
|
} else {
|
|
webChannel.onopen();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'broadcast',
|
|
value: function broadcast(webChannel, data) {
|
|
return new Promise(function (resolve, reject) {
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = webChannel.channels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var c = _step.value;
|
|
|
|
c.send(data);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
resolve();
|
|
});
|
|
}
|
|
}, {
|
|
key: 'sendTo',
|
|
value: function sendTo(id, webChannel, data) {
|
|
return new Promise(function (resolve, reject) {
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = webChannel.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var c = _step2.value;
|
|
|
|
if (c.peerID == id) {
|
|
c.send(data);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
_iterator2.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
|
|
resolve();
|
|
});
|
|
}
|
|
}, {
|
|
key: 'leave',
|
|
value: function leave(webChannel) {
|
|
this.broadcast(webChannel);
|
|
}
|
|
}, {
|
|
key: '_generateID',
|
|
value: function _generateID() {
|
|
var MIN_LENGTH = 10;
|
|
var DELTA_LENGTH = 10;
|
|
var MASK = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
var length = MIN_LENGTH + Math.round(Math.random() * DELTA_LENGTH);
|
|
var maskLastIndex = MASK.length - 1;
|
|
var result = '';
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
result += MASK[Math.round(Math.random() * maskLastIndex)];
|
|
}
|
|
return result;
|
|
}
|
|
}]);
|
|
|
|
return FullyConnectedService;
|
|
}();
|
|
|
|
exports.default = FullyConnectedService;
|
|
|
|
/***/ },
|
|
/* 6 */
|
|
/***/ function(module, exports) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var StarTopologyService = function () {
|
|
function StarTopologyService() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, StarTopologyService);
|
|
}
|
|
|
|
_createClass(StarTopologyService, [{
|
|
key: 'broadcast',
|
|
value: function broadcast(webChannel, data) {
|
|
return new Promise(function (resolve, reject) {
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = webChannel.channels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var c = _step.value;
|
|
|
|
var msg = undefined;
|
|
if (data.type === 'PING') {
|
|
var date = new Date().getTime();
|
|
// webChannel.lastPing = date;
|
|
msg = JSON.stringify([0, 'PING', date]);
|
|
} else {
|
|
msg = JSON.stringify([c.seq++, data.type, webChannel.id, data.msg]);
|
|
}
|
|
c.send(msg);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
resolve();
|
|
});
|
|
}
|
|
}, {
|
|
key: 'sendTo',
|
|
value: function sendTo(id, webChannel, data) {
|
|
return new Promise(function (resolve, reject) {
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = webChannel.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var c = _step2.value;
|
|
|
|
var msg = JSON.stringify([c.seq++, data.type, id, data.msg]);
|
|
c.send(msg);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
_iterator2.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
|
|
resolve();
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return StarTopologyService;
|
|
}();
|
|
|
|
exports.default = StarTopologyService;
|
|
|
|
/***/ },
|
|
/* 7 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _constants = __webpack_require__(3);
|
|
|
|
var cs = _interopRequireWildcard(_constants);
|
|
|
|
var _ServiceProvider = __webpack_require__(4);
|
|
|
|
var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var WEBRTC_DATA = 0;
|
|
var CONNECT_WITH = 1;
|
|
var CONNECT_WITH_SUCCEED = 2;
|
|
|
|
var WebRTCService = function () {
|
|
function WebRTCService() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, WebRTCService);
|
|
|
|
this.NAME = this.constructor.name;
|
|
this.protocol = _ServiceProvider2.default.get(cs.EXCHANGEPROTOCOL_SERVICE);
|
|
this.defaults = {
|
|
signaling: 'ws://localhost:8000',
|
|
webRTCOptions: {
|
|
iceServers: [{
|
|
urls: ['stun:23.21.150.121', 'stun:stun.l.google.com:19302']
|
|
}, {
|
|
urls: 'turn:numb.viagenie.ca',
|
|
credential: 'webrtcdemo',
|
|
username: 'louis%40mozilla.com'
|
|
}]
|
|
}
|
|
};
|
|
this.settings = Object.assign({}, this.defaults, options);
|
|
|
|
// Declare WebRTC related global(window) constructors
|
|
this.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.msRTCPeerConnection;
|
|
|
|
this.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.RTCIceCandidate || window.msRTCIceCandidate;
|
|
|
|
this.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription || window.msRTCSessionDescription;
|
|
}
|
|
|
|
_createClass(WebRTCService, [{
|
|
key: 'connect',
|
|
value: function connect(newPeerID, webChannel, peerID) {
|
|
webChannel.topologyService.sendTo(peerID, webChannel, this._msg(CONNECT_WITH, { key: newPeerID, intermediaryID: webChannel.myID }));
|
|
}
|
|
}, {
|
|
key: 'open',
|
|
value: function open(onchannel) {
|
|
var _this = this;
|
|
|
|
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
var defaults = {
|
|
key: this._randomKey()
|
|
};
|
|
var settings = Object.assign({}, this.settings, defaults, options);
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
var connections = [];
|
|
var socket = new window.WebSocket(settings.signaling);
|
|
socket.onopen = function () {
|
|
socket.send(JSON.stringify({ key: settings.key }));
|
|
resolve({ url: _this.settings.signaling, key: settings.key });
|
|
};
|
|
socket.onmessage = function (e) {
|
|
var msg = JSON.parse(e.data);
|
|
if (Reflect.has(msg, 'id') && Reflect.has(msg, 'data')) {
|
|
if (Reflect.has(msg.data, 'offer')) {
|
|
(function () {
|
|
var connection = new _this.RTCPeerConnection(settings.webRTCOptions);
|
|
connections.push(connection);
|
|
connection.ondatachannel = function (e) {
|
|
e.channel.onopen = function () {
|
|
onchannel(e.channel);
|
|
};
|
|
};
|
|
connection.onicecandidate = function (e) {
|
|
if (e.candidate !== null) {
|
|
var candidate = {
|
|
candidate: e.candidate.candidate,
|
|
sdpMLineIndex: e.candidate.sdpMLineIndex
|
|
};
|
|
socket.send(JSON.stringify({ id: msg.id, data: { candidate: candidate } }));
|
|
}
|
|
};
|
|
var sd = Object.assign(new _this.RTCSessionDescription(), msg.data.offer);
|
|
connection.setRemoteDescription(sd, function () {
|
|
connection.createAnswer(function (answer) {
|
|
connection.setLocalDescription(answer, function () {
|
|
socket.send(JSON.stringify({
|
|
id: msg.id,
|
|
data: { answer: connection.localDescription.toJSON() } }));
|
|
}, function () {});
|
|
}, function () {});
|
|
}, function () {});
|
|
})();
|
|
} else if (Reflect.has(msg.data, 'candidate')) {
|
|
var candidate = new _this.RTCIceCandidate(msg.data.candidate);
|
|
connections[msg.id].addIceCandidate(candidate);
|
|
}
|
|
}
|
|
};
|
|
socket.onerror = reject;
|
|
});
|
|
}
|
|
}, {
|
|
key: 'join',
|
|
value: function join(key) {
|
|
var _this2 = this;
|
|
|
|
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
var settings = Object.assign({}, this.settings, options);
|
|
return new Promise(function (resolve, reject) {
|
|
var connection = undefined;
|
|
var socket = new window.WebSocket(settings.signaling);
|
|
socket.onopen = function () {
|
|
connection = new _this2.RTCPeerConnection(settings.webRTCOptions);
|
|
connection.onicecandidate = function (e) {
|
|
if (e.candidate !== null) {
|
|
var candidate = {
|
|
candidate: e.candidate.candidate,
|
|
sdpMLineIndex: e.candidate.sdpMLineIndex
|
|
};
|
|
socket.send(JSON.stringify({ data: { candidate: candidate } }));
|
|
}
|
|
};
|
|
var dc = connection.createDataChannel(key);
|
|
dc.onopen = function () {
|
|
resolve(dc);
|
|
};
|
|
connection.createOffer(function (offer) {
|
|
connection.setLocalDescription(offer, function () {
|
|
socket.send(JSON.stringify({ join: key, data: { offer: connection.localDescription.toJSON() } }));
|
|
}, reject);
|
|
}, reject);
|
|
};
|
|
socket.onclose = function (e) {
|
|
reject(e);
|
|
};
|
|
socket.onmessage = function (e) {
|
|
var msg = JSON.parse(e.data);
|
|
if (Reflect.has(msg, 'data')) {
|
|
if (Reflect.has(msg.data, 'answer')) {
|
|
var sd = Object.assign(new _this2.RTCSessionDescription(), msg.data.answer);
|
|
connection.setRemoteDescription(sd, function () {}, reject);
|
|
} else if (Reflect.has(msg.data, 'candidate')) {
|
|
var candidate = new _this2.RTCIceCandidate(msg.data.candidate);
|
|
connection.addIceCandidate(candidate);
|
|
} else {
|
|
reject();
|
|
}
|
|
} else {
|
|
reject();
|
|
}
|
|
};
|
|
socket.onerror = reject;
|
|
});
|
|
}
|
|
}, {
|
|
key: '_randomKey',
|
|
value: function _randomKey() {
|
|
var MIN_LENGTH = 10;
|
|
var DELTA_LENGTH = 10;
|
|
var MASK = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
var result = '';
|
|
var length = MIN_LENGTH + Math.round(Math.random() * DELTA_LENGTH);
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
result += MASK[Math.round(Math.random() * (MASK.length - 1))];
|
|
}
|
|
return result;
|
|
}
|
|
}, {
|
|
key: '_msg',
|
|
value: function _msg(code, data) {
|
|
var msg = { service: this.constructor.name };
|
|
msg.data = {};
|
|
msg.data.code = code;
|
|
Object.assign(msg.data, data);
|
|
return this.protocol.message(cs.SERVICE_DATA, msg);
|
|
}
|
|
}, {
|
|
key: 'onmessage',
|
|
value: function onmessage(channel, msg) {
|
|
var _this3 = this;
|
|
|
|
var webChannel = channel.webChannel;
|
|
if (!Reflect.has(webChannel, 'connections')) {
|
|
webChannel.connections = new Map();
|
|
}
|
|
switch (msg.code) {
|
|
case WEBRTC_DATA:
|
|
if (webChannel.myID === msg.recipientPeerID) {
|
|
if (Reflect.has(msg, 'sdp')) {
|
|
if (msg.sdp.type === 'offer') {
|
|
(function () {
|
|
var connection = new _this3.RTCPeerConnection(_this3.settings.webRTCOptions);
|
|
webChannel.connections.set(msg.senderPeerID, connection);
|
|
connection.ondatachannel = function (e) {
|
|
e.channel.onopen = function () {
|
|
e.channel.peerID = msg.senderPeerID;
|
|
e.channel.webChannel = webChannel;
|
|
e.channel.onmessage = _this3.protocol.onmessage;
|
|
webChannel.channels.add(e.channel);
|
|
e.channel.onclose = function () {
|
|
webChannel.onLeaving(e.channel.peerID);
|
|
webChannel.channels.delete(e.channel);
|
|
};
|
|
};
|
|
};
|
|
connection.onicecandidate = function (e) {
|
|
if (e.candidate !== null) {
|
|
var candidate = {
|
|
candidate: e.candidate.candidate,
|
|
sdpMLineIndex: e.candidate.sdpMLineIndex
|
|
};
|
|
channel.send(_this3._msg(WEBRTC_DATA, {
|
|
senderPeerID: webChannel.myID,
|
|
recipientPeerID: msg.senderPeerID,
|
|
candidate: candidate
|
|
}));
|
|
}
|
|
};
|
|
var sd = Object.assign(new _this3.RTCSessionDescription(), msg.sdp);
|
|
connection.setRemoteDescription(sd, function () {
|
|
connection.createAnswer(function (answer) {
|
|
connection.setLocalDescription(answer, function () {
|
|
channel.send(_this3._msg(WEBRTC_DATA, {
|
|
senderPeerID: webChannel.myID,
|
|
recipientPeerID: msg.senderPeerID,
|
|
sdp: connection.localDescription.toJSON()
|
|
}));
|
|
}, function () {});
|
|
}, function () {});
|
|
}, function () {});
|
|
})();
|
|
} else if (msg.sdp.type === 'answer') {
|
|
var sd = Object.assign(new this.RTCSessionDescription(), msg.sdp);
|
|
webChannel.connections.get(msg.senderPeerID).setRemoteDescription(sd, function () {}, function () {});
|
|
}
|
|
} else if (Reflect.has(msg, 'candidate')) {
|
|
webChannel.connections.get(msg.senderPeerID).addIceCandidate(new this.RTCIceCandidate(msg.candidate));
|
|
}
|
|
} else {
|
|
var data = this._msg(WEBRTC_DATA, msg);
|
|
if (webChannel.aboutToJoin.has(msg.recipientPeerID)) {
|
|
webChannel.aboutToJoin.get(msg.recipientPeerID).send(data);
|
|
} else {
|
|
webChannel.topologyService.sendTo(msg.recipientPeerID, webChannel, data);
|
|
}
|
|
}
|
|
break;
|
|
case CONNECT_WITH:
|
|
var connection = new this.RTCPeerConnection(this.settings.webRTCOptions);
|
|
connection.onicecandidate = function (e) {
|
|
if (e.candidate !== null) {
|
|
var candidate = {
|
|
candidate: e.candidate.candidate,
|
|
sdpMLineIndex: e.candidate.sdpMLineIndex
|
|
};
|
|
webChannel.topologyService.sendTo(msg.intermediaryID, webChannel, _this3._msg(WEBRTC_DATA, {
|
|
senderPeerID: webChannel.myID,
|
|
recipientPeerID: msg.key,
|
|
candidate: candidate
|
|
}));
|
|
}
|
|
};
|
|
var dc = connection.createDataChannel(msg.key);
|
|
dc.onopen = function () {
|
|
if (!Reflect.has(webChannel, 'aboutToJoin')) {
|
|
webChannel.aboutToJoin = new Map();
|
|
}
|
|
webChannel.aboutToJoin.set(dc.label, dc);
|
|
dc.onmessage = _this3.protocol.onmessage;
|
|
dc.peerID = dc.label;
|
|
dc.webChannel = webChannel;
|
|
webChannel.topologyService.sendTo(msg.intermediaryID, webChannel, _this3._msg(CONNECT_WITH_SUCCEED, {
|
|
senderPeerID: webChannel.myID,
|
|
recipientPeerID: dc.label
|
|
}));
|
|
};
|
|
connection.createOffer(function (offer) {
|
|
connection.setLocalDescription(offer, function () {
|
|
webChannel.topologyService.sendTo(msg.intermediaryID, webChannel, _this3._msg(WEBRTC_DATA, {
|
|
senderPeerID: webChannel.myID,
|
|
recipientPeerID: msg.key,
|
|
sdp: connection.localDescription.toJSON()
|
|
}));
|
|
webChannel.connections.set(msg.key, connection);
|
|
}, function () {});
|
|
}, function () {});
|
|
break;
|
|
case CONNECT_WITH_SUCCEED:
|
|
webChannel.connectionSucceed(msg.senderPeerID, msg.recipientPeerID);
|
|
break;
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return WebRTCService;
|
|
}();
|
|
|
|
exports.default = WebRTCService;
|
|
|
|
/***/ },
|
|
/* 8 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _constants = __webpack_require__(3);
|
|
|
|
var cs = _interopRequireWildcard(_constants);
|
|
|
|
var _ServiceProvider = __webpack_require__(4);
|
|
|
|
var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var WebSocketService = function () {
|
|
function WebSocketService() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, WebSocketService);
|
|
|
|
this.NAME = this.constructor.name;
|
|
this.protocol = _ServiceProvider2.default.get(cs.EXCHANGEPROTOCOL_SERVICE);
|
|
this.defaults = {
|
|
signaling: 'ws://localhost:9000'
|
|
};
|
|
this.settings = Object.assign({}, this.defaults, options);
|
|
}
|
|
|
|
_createClass(WebSocketService, [{
|
|
key: 'join',
|
|
value: function join(key) {
|
|
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
|
|
|
var settings = Object.assign({}, this.settings, options);
|
|
return new Promise(function (resolve, reject) {
|
|
var connection = undefined;
|
|
var socket = new window.WebSocket(settings.signaling);
|
|
socket.seq = 1;
|
|
socket.facade = options.facade || null;
|
|
socket.onopen = function () {
|
|
if (key && key !== '') {
|
|
socket.send(JSON.stringify([socket.seq++, 'JOIN', key]));
|
|
} else {
|
|
socket.send(JSON.stringify([socket.seq++, 'JOIN']));
|
|
}
|
|
resolve(socket);
|
|
};
|
|
socket.onerror = reject;
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return WebSocketService;
|
|
}();
|
|
|
|
exports.default = WebSocketService;
|
|
|
|
/***/ },
|
|
/* 9 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _constants = __webpack_require__(3);
|
|
|
|
var cs = _interopRequireWildcard(_constants);
|
|
|
|
var _ServiceProvider = __webpack_require__(4);
|
|
|
|
var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var ExchangeProtocolService = function () {
|
|
function ExchangeProtocolService() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, ExchangeProtocolService);
|
|
}
|
|
|
|
_createClass(ExchangeProtocolService, [{
|
|
key: 'onmessage',
|
|
value: function onmessage(e) {
|
|
var msg = JSON.parse(e.data);
|
|
var channel = e.currentTarget;
|
|
var webChannel = channel.webChannel;
|
|
|
|
switch (msg.code) {
|
|
case cs.USER_DATA:
|
|
webChannel.onmessage(msg.id, msg.data);
|
|
break;
|
|
case cs.GET_HISTORY:
|
|
webChannel.onPeerMessage(msg.id, msg.code);
|
|
break;
|
|
case cs.SERVICE_DATA:
|
|
var service = _ServiceProvider2.default.get(msg.service);
|
|
service.onmessage(channel, msg.data);
|
|
break;
|
|
case cs.YOUR_NEW_ID:
|
|
// TODO: change names
|
|
webChannel.myID = msg.newID;
|
|
channel.peerID = msg.myID;
|
|
break;
|
|
case cs.JOIN_START:
|
|
// 2.1) Send to the new client the webChannel topology
|
|
webChannel.topology = msg.topology;
|
|
webChannel.topologyService = _ServiceProvider2.default.get(msg.topology);
|
|
break;
|
|
case cs.JOIN_FINISH:
|
|
webChannel.topologyService.addFinish(webChannel, msg.id);
|
|
if (msg.id != webChannel.myID) {
|
|
// A new user has just registered
|
|
webChannel.onJoining(msg.id);
|
|
} else {
|
|
(function () {
|
|
// We're fully synced, trigger onJoining for all existing users
|
|
var waitForOnJoining = function waitForOnJoining() {
|
|
if (typeof webChannel.onJoining !== "function") {
|
|
setTimeout(waitForOnJoining, 500);
|
|
return;
|
|
}
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = webChannel.channels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var c = _step.value;
|
|
|
|
webChannel.onJoining(c.peerID);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
waitForOnJoining();
|
|
})();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}, {
|
|
key: 'message',
|
|
value: function message(code, data) {
|
|
var msg = { code: code };
|
|
switch (code) {
|
|
case cs.USER_DATA:
|
|
msg.id = data.id;
|
|
msg.data = data.data;
|
|
break;
|
|
case cs.GET_HISTORY:
|
|
msg.id = data.id;
|
|
break;
|
|
case cs.SERVICE_DATA:
|
|
msg.service = data.service;
|
|
msg.data = Object.assign({}, data.data);
|
|
break;
|
|
case cs.YOUR_NEW_ID:
|
|
msg.newID = data.newID;
|
|
msg.myID = data.myID;
|
|
break;
|
|
case cs.JOIN_START:
|
|
msg.topology = data;
|
|
break;
|
|
case cs.JOIN_FINISH:
|
|
msg.id = data;
|
|
break;
|
|
}
|
|
return JSON.stringify(msg);
|
|
}
|
|
}]);
|
|
|
|
return ExchangeProtocolService;
|
|
}();
|
|
|
|
exports.default = ExchangeProtocolService;
|
|
|
|
/***/ },
|
|
/* 10 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _constants = __webpack_require__(3);
|
|
|
|
var cs = _interopRequireWildcard(_constants);
|
|
|
|
var _ServiceProvider = __webpack_require__(4);
|
|
|
|
var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var WebSocketProtocolService = function () {
|
|
function WebSocketProtocolService() {
|
|
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
|
|
|
_classCallCheck(this, WebSocketProtocolService);
|
|
}
|
|
|
|
_createClass(WebSocketProtocolService, [{
|
|
key: 'onmessage',
|
|
value: function onmessage(e) {
|
|
var msg = JSON.parse(e.data);
|
|
var socket = e.currentTarget;
|
|
var webChannel = socket.webChannel;
|
|
var topology = cs.STAR_SERVICE;
|
|
var topologyService = _ServiceProvider2.default.get(topology);
|
|
var HISTORY_KEEPER = '_HISTORY_KEEPER_';
|
|
|
|
if (msg[0] !== 0) {
|
|
return;
|
|
}
|
|
if (msg[1] === 'IDENT') {
|
|
socket.uid = msg[2];
|
|
webChannel.myID = msg[2];
|
|
webChannel.peers = [];
|
|
webChannel.topology = topology;
|
|
return;
|
|
}
|
|
if (msg[1] === 'PING') {
|
|
msg[1] = 'PONG';
|
|
socket.send(JSON.stringify(msg));
|
|
return;
|
|
}
|
|
if (msg[1] === 'PONG') {
|
|
var lag = new Date().getTime() - msg[2];
|
|
webChannel.getLag = function () {
|
|
return lag;
|
|
};
|
|
return;
|
|
}
|
|
if (msg[2] === 'MSG') {}
|
|
// We have received a new direct message from another user
|
|
if (msg[2] === 'MSG' && msg[3] === socket.uid) {
|
|
// If it comes form the history keeper, send it to the user
|
|
if (msg[1] === HISTORY_KEEPER) {
|
|
var msgHistory = JSON.parse(msg[4]);
|
|
webChannel.onmessage(msgHistory[1], msgHistory[4]);
|
|
}
|
|
}
|
|
if (msg[2] === 'JOIN' && (webChannel.id == null || webChannel.id === msg[3])) {
|
|
if (!webChannel.id) {
|
|
// New unnamed channel : get its name from the first "JOIN" message
|
|
if (!window.location.hash) {
|
|
var chanName = window.location.hash = msg[3];
|
|
}
|
|
webChannel.id = msg[3];
|
|
}
|
|
|
|
if (msg[1] === socket.uid) {
|
|
// If the user catches himself registering, he is synchronized with the server
|
|
webChannel.onopen();
|
|
} else {
|
|
// Trigger onJoining() when another user is joining the channel
|
|
// Register the user in the list of peers in the channel
|
|
var linkQuality = msg[1] === HISTORY_KEEPER ? 1000 : 0;
|
|
var sendToPeer = function sendToPeer(data) {
|
|
topologyService.sendTo(msg[1], webChannel, { type: 'MSG', msg: data });
|
|
};
|
|
var peer = { id: msg[1], connector: socket, linkQuality: linkQuality, send: sendToPeer };
|
|
if (webChannel.peers.indexOf(peer) === -1) {
|
|
webChannel.peers.push(peer);
|
|
}
|
|
|
|
if (msg[1] !== HISTORY_KEEPER) {
|
|
// Trigger onJoining with that peer once the function is loaded (i.e. once the channel is synced)
|
|
var waitForOnJoining = function waitForOnJoining() {
|
|
if (typeof webChannel.onJoining !== "function") {
|
|
setTimeout(waitForOnJoining, 500);
|
|
return;
|
|
}
|
|
webChannel.onJoining(msg[1]);
|
|
};
|
|
waitForOnJoining();
|
|
}
|
|
}
|
|
}
|
|
// We have received a new message in that channel from another peer
|
|
if (msg[2] === 'MSG' && msg[3] === webChannel.id) {
|
|
// Find the peer who sent the message and display it
|
|
//TODO Use Peer instead of peer.id (msg[1]) :
|
|
if (typeof webChannel.onmessage === "function") webChannel.onmessage(msg[1], msg[4]);
|
|
}
|
|
// Someone else has left the channel, remove him from the list of peers
|
|
if (msg[2] === 'LEAVE' && msg[3] === webChannel.id) {
|
|
//TODO Use Peer instead of peer.id (msg[1]) :
|
|
if (typeof webChannel.onLeaving === "function") webChannel.onLeaving(msg[1], webChannel);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'message',
|
|
value: function message(code, data) {
|
|
var type = undefined;
|
|
switch (code) {
|
|
case cs.USER_DATA:
|
|
type = 'MSG';
|
|
break;
|
|
case cs.JOIN_START:
|
|
type = 'JOIN';
|
|
break;
|
|
case cs.PING:
|
|
type = 'PING';
|
|
break;
|
|
}
|
|
return { type: type, msg: data.data };
|
|
}
|
|
}]);
|
|
|
|
return WebSocketProtocolService;
|
|
}();
|
|
|
|
exports.default = WebSocketProtocolService;
|
|
|
|
/***/ }
|
|
/******/ ])
|
|
});
|
|
; |