Replace the Netflux old client (netflux.js) by the Netflux2 client.
Move the WebRTC peer-to-peer use case in /padrtc, which still uses the old Netflux client Use es6-promises.min.js to solve a issue with some browser and the new Netflux client
This commit is contained in:
1 parent
cf9f60bd57
commit
0b3d6e15b8
14 files changed
+2628
-160
No files matched your search
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* @overview es6-promise - a tiny implementation of Promises/A+.
|
||||
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
|
||||
* @license Licensed under MIT license
|
||||
* See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
|
||||
* @version 3.2.1
|
||||
*/
|
||||
|
||||
(function(){"use strict";function t(t){return"function"==typeof t||"object"==typeof t&&null!==t}function e(t){return"function"==typeof t}function n(t){G=t}function r(t){Q=t}function o(){return function(){process.nextTick(a)}}function i(){return function(){B(a)}}function s(){var t=0,e=new X(a),n=document.createTextNode("");return e.observe(n,{characterData:!0}),function(){n.data=t=++t%2}}function u(){var t=new MessageChannel;return t.port1.onmessage=a,function(){t.port2.postMessage(0)}}function c(){return function(){setTimeout(a,1)}}function a(){for(var t=0;J>t;t+=2){var e=tt[t],n=tt[t+1];e(n),tt[t]=void 0,tt[t+1]=void 0}J=0}function f(){try{var t=require,e=t("vertx");return B=e.runOnLoop||e.runOnContext,i()}catch(n){return c()}}function l(t,e){var n=this,r=new this.constructor(p);void 0===r[rt]&&k(r);var o=n._state;if(o){var i=arguments[o-1];Q(function(){x(o,r,i,n._result)})}else E(n,r,t,e);return r}function h(t){var e=this;if(t&&"object"==typeof t&&t.constructor===e)return t;var n=new e(p);return g(n,t),n}function p(){}function _(){return new TypeError("You cannot resolve a promise with itself")}function d(){return new TypeError("A promises callback cannot return that same promise.")}function v(t){try{return t.then}catch(e){return ut.error=e,ut}}function y(t,e,n,r){try{t.call(e,n,r)}catch(o){return o}}function m(t,e,n){Q(function(t){var r=!1,o=y(n,e,function(n){r||(r=!0,e!==n?g(t,n):S(t,n))},function(e){r||(r=!0,j(t,e))},"Settle: "+(t._label||" unknown promise"));!r&&o&&(r=!0,j(t,o))},t)}function b(t,e){e._state===it?S(t,e._result):e._state===st?j(t,e._result):E(e,void 0,function(e){g(t,e)},function(e){j(t,e)})}function w(t,n,r){n.constructor===t.constructor&&r===et&&constructor.resolve===nt?b(t,n):r===ut?j(t,ut.error):void 0===r?S(t,n):e(r)?m(t,n,r):S(t,n)}function g(e,n){e===n?j(e,_()):t(n)?w(e,n,v(n)):S(e,n)}function A(t){t._onerror&&t._onerror(t._result),T(t)}function S(t,e){t._state===ot&&(t._result=e,t._state=it,0!==t._subscribers.length&&Q(T,t))}function j(t,e){t._state===ot&&(t._state=st,t._result=e,Q(A,t))}function E(t,e,n,r){var o=t._subscribers,i=o.length;t._onerror=null,o[i]=e,o[i+it]=n,o[i+st]=r,0===i&&t._state&&Q(T,t)}function T(t){var e=t._subscribers,n=t._state;if(0!==e.length){for(var r,o,i=t._result,s=0;s<e.length;s+=3)r=e[s],o=e[s+n],r?x(n,r,o,i):o(i);t._subscribers.length=0}}function M(){this.error=null}function P(t,e){try{return t(e)}catch(n){return ct.error=n,ct}}function x(t,n,r,o){var i,s,u,c,a=e(r);if(a){if(i=P(r,o),i===ct?(c=!0,s=i.error,i=null):u=!0,n===i)return void j(n,d())}else i=o,u=!0;n._state!==ot||(a&&u?g(n,i):c?j(n,s):t===it?S(n,i):t===st&&j(n,i))}function C(t,e){try{e(function(e){g(t,e)},function(e){j(t,e)})}catch(n){j(t,n)}}function O(){return at++}function k(t){t[rt]=at++,t._state=void 0,t._result=void 0,t._subscribers=[]}function Y(t){return new _t(this,t).promise}function q(t){var e=this;return new e(I(t)?function(n,r){for(var o=t.length,i=0;o>i;i++)e.resolve(t[i]).then(n,r)}:function(t,e){e(new TypeError("You must pass an array to race."))})}function F(t){var e=this,n=new e(p);return j(n,t),n}function D(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function K(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function L(t){this[rt]=O(),this._result=this._state=void 0,this._subscribers=[],p!==t&&("function"!=typeof t&&D(),this instanceof L?C(this,t):K())}function N(t,e){this._instanceConstructor=t,this.promise=new t(p),this.promise[rt]||k(this.promise),Array.isArray(e)?(this._input=e,this.length=e.length,this._remaining=e.length,this._result=new Array(this.length),0===this.length?S(this.promise,this._result):(this.length=this.length||0,this._enumerate(),0===this._remaining&&S(this.promise,this._result))):j(this.promise,U())}function U(){return new Error("Array Methods must be provided an Array")}function W(){var t;if("undefined"!=typeof global)t=global;else if("undefined"!=typeof self)t=self;else try{t=Function("return this")()}catch(e){throw new Error("polyfill failed because global object is unavailable in this environment")}var n=t.Promise;(!n||"[object Promise]"!==Object.prototype.toString.call(n.resolve())||n.cast)&&(t.Promise=pt)}var z;z=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)};var B,G,H,I=z,J=0,Q=function(t,e){tt[J]=t,tt[J+1]=e,J+=2,2===J&&(G?G(a):H())},R="undefined"!=typeof window?window:void 0,V=R||{},X=V.MutationObserver||V.WebKitMutationObserver,Z="undefined"==typeof self&&"undefined"!=typeof process&&"[object process]"==={}.toString.call(process),$="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,tt=new Array(1e3);H=Z?o():X?s():$?u():void 0===R&&"function"==typeof require?f():c();var et=l,nt=h,rt=Math.random().toString(36).substring(16),ot=void 0,it=1,st=2,ut=new M,ct=new M,at=0,ft=Y,ltLine truncated
|
||||
@@ -0,0 +1,225 @@
|
||||
/*global: WebSocket */
|
||||
define(() => {
|
||||
'use strict';
|
||||
const MAX_LAG_BEFORE_PING = 15000;
|
||||
const MAX_LAG_BEFORE_DISCONNECT = 30000;
|
||||
const PING_CYCLE = 5000;
|
||||
const REQUEST_TIMEOUT = 5000;
|
||||
|
||||
const now = () => new Date().getTime();
|
||||
|
||||
const networkSendTo = (ctx, peerId, content) => {
|
||||
const seq = ctx.seq++;
|
||||
ctx.ws.send(JSON.stringify([seq, 'MSG', peerId, content]));
|
||||
return new Promise((res, rej) => {
|
||||
ctx.requests[seq] = { reject: rej, resolve: res, time: now() };
|
||||
});
|
||||
};
|
||||
|
||||
const channelBcast = (ctx, chanId, content) => {
|
||||
const chan = ctx.channels[chanId];
|
||||
if (!chan) { throw new Error("no such channel " + chanId); }
|
||||
const seq = ctx.seq++;
|
||||
ctx.ws.send(JSON.stringify([seq, 'MSG', chanId, content]));
|
||||
return new Promise((res, rej) => {
|
||||
ctx.requests[seq] = { reject: rej, resolve: res, time: now() };
|
||||
});
|
||||
};
|
||||
|
||||
const channelLeave = (ctx, chanId, reason) => {
|
||||
const chan = ctx.channels[chanId];
|
||||
if (!chan) { throw new Error("no such channel " + chanId); }
|
||||
delete ctx.channels[chanId];
|
||||
ctx.ws.send(JSON.stringify([ctx.seq++, 'LEAVE', chanId, reason]));
|
||||
};
|
||||
|
||||
const makeEventHandlers = (ctx, mappings) => {
|
||||
return (name, handler) => {
|
||||
const handlers = mappings[name];
|
||||
if (!handlers) { throw new Error("no such event " + name); }
|
||||
handlers.push(handler);
|
||||
};
|
||||
};
|
||||
|
||||
const mkChannel = (ctx, id) => {
|
||||
const internal = {
|
||||
onMessage: [],
|
||||
onJoin: [],
|
||||
onLeave: [],
|
||||
members: [],
|
||||
jSeq: ctx.seq++
|
||||
};
|
||||
const chan = {
|
||||
_: internal,
|
||||
id: id,
|
||||
members: internal.members,
|
||||
bcast: (msg) => channelBcast(ctx, chan.id, msg),
|
||||
leave: (reason) => channelLeave(ctx, chan.id, reason),
|
||||
on: makeEventHandlers(ctx, { message:
|
||||
internal.onMessage, join: internal.onJoin, leave: internal.onLeave })
|
||||
};
|
||||
ctx.requests[internal.jSeq] = chan;
|
||||
ctx.ws.send(JSON.stringify([internal.jSeq, 'JOIN', id]));
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
chan._.resolve = res;
|
||||
chan._.reject = rej;
|
||||
})
|
||||
};
|
||||
|
||||
const mkNetwork = (ctx) => {
|
||||
const network = {
|
||||
webChannels: ctx.channels,
|
||||
getLag: () => (ctx.lag),
|
||||
sendto: (peerId, content) => (networkSendTo(ctx, peerId, content)),
|
||||
join: (chanId) => (mkChannel(ctx, chanId)),
|
||||
on: makeEventHandlers(ctx, { message: ctx.onMessage, disconnect: ctx.onDisconnect })
|
||||
};
|
||||
network.__defineGetter__("webChannels", () => {
|
||||
return Object.keys(ctx.channels).map((k) => (ctx.channels[k]));
|
||||
});
|
||||
return network;
|
||||
};
|
||||
|
||||
const onMessage = (ctx, evt) => {
|
||||
let msg;
|
||||
try { msg = JSON.parse(evt.data); } catch (e) { console.log(e.stack); return; }
|
||||
if (msg[0] !== 0) {
|
||||
const req = ctx.requests[msg[0]];
|
||||
if (!req) {
|
||||
console.log("error: " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
delete ctx.requests[msg[0]];
|
||||
if (msg[1] === 'ACK') {
|
||||
if (req.ping) { // ACK of a PING
|
||||
ctx.lag = now() - Number(req.ping);
|
||||
return;
|
||||
}
|
||||
req.resolve();
|
||||
} else if (msg[1] === 'JACK') {
|
||||
if (req._) {
|
||||
// Channel join request...
|
||||
if (!msg[2]) { throw new Error("wrong type of ACK for channel join"); }
|
||||
req.id = msg[2];
|
||||
ctx.channels[req.id] = req;
|
||||
return;
|
||||
}
|
||||
req.resolve();
|
||||
} else if (msg[1] === 'ERROR') {
|
||||
req.reject({ type: msg[2], message: msg[3] });
|
||||
} else {
|
||||
req.reject({ type: 'UNKNOWN', message: JSON.stringify(msg) });
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (msg[2] === 'IDENT') {
|
||||
ctx.uid = msg[3];
|
||||
|
||||
setInterval(() => {
|
||||
if (now() - ctx.timeOfLastMessage < MAX_LAG_BEFORE_PING) { return; }
|
||||
let seq = ctx.seq++;
|
||||
let currentDate = now();
|
||||
ctx.requests[seq] = {time: now(), ping: currentDate};
|
||||
ctx.ws.send(JSON.stringify([seq, 'PING', currentDate]));
|
||||
if (now() - ctx.timeOfLastMessage > MAX_LAG_BEFORE_DISCONNECT) {
|
||||
ctx.ws.close();
|
||||
}
|
||||
}, PING_CYCLE);
|
||||
|
||||
return;
|
||||
} else if (!ctx.uid) {
|
||||
// extranious message, waiting for an ident.
|
||||
return;
|
||||
}
|
||||
if (msg[2] === 'PING') {
|
||||
msg[1] = 'PONG';
|
||||
ctx.ws.send(JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg[2] === 'MSG') {
|
||||
let handlers;
|
||||
if (msg[3] === ctx.uid) {
|
||||
handlers = ctx.onMessage;
|
||||
} else {
|
||||
const chan = ctx.channels[msg[3]];
|
||||
if (!chan) {
|
||||
console.log("message to non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
handlers = chan._.onMessage;
|
||||
}
|
||||
handlers.forEach((h) => {
|
||||
try { h(msg[4], msg[1]); } catch (e) { console.log(e.stack); }
|
||||
});
|
||||
}
|
||||
|
||||
if (msg[2] === 'LEAVE') {
|
||||
const chan = ctx.channels[msg[3]];
|
||||
if (!chan) {
|
||||
console.log("leaving non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
chan._.onLeave.forEach((h) => {
|
||||
try { h(msg[1], msg[4]); } catch (e) { console.log(e.stack); }
|
||||
});
|
||||
}
|
||||
|
||||
if (msg[2] === 'JOIN') {
|
||||
const chan = ctx.channels[msg[3]];
|
||||
if (!chan) {
|
||||
console.log("ERROR: join to non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
// have we yet fully joined the chan?
|
||||
const synced = (chan._.members.indexOf(ctx.uid) !== -1);
|
||||
chan._.members.push(msg[1]);
|
||||
if (!synced && msg[1] === ctx.uid) {
|
||||
// sync the channel join event
|
||||
chan.myID = ctx.uid;
|
||||
chan._.resolve(chan);
|
||||
}
|
||||
if (synced) {
|
||||
chan._.onJoin.forEach((h) => {
|
||||
try { h(msg[1]); } catch (e) { console.log(e.stack); }
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const connect = (websocketURL) => {
|
||||
let ctx = {
|
||||
ws: new WebSocket(websocketURL),
|
||||
seq: 1,
|
||||
lag: 0,
|
||||
uid: null,
|
||||
network: null,
|
||||
channels: {},
|
||||
onMessage: [],
|
||||
onDisconnect: [],
|
||||
requests: {}
|
||||
};
|
||||
setInterval(() => {
|
||||
for (let id in ctx.requests) {
|
||||
const req = ctx.requests[id];
|
||||
if (now() - req.time > REQUEST_TIMEOUT) {
|
||||
delete ctx.requests[id];
|
||||
req.reject({ type: 'TIMEOUT', message: 'waited ' + now() - req.time + 'ms' });
|
||||
}
|
||||
}
|
||||
}, 5000);
|
||||
ctx.network = mkNetwork(ctx);
|
||||
ctx.ws.onmessage = (msg) => (onMessage(ctx, msg));
|
||||
ctx.ws.onclose = (evt) => {
|
||||
ctx.onDisconnect.forEach((h) => {
|
||||
try { h(evt.reason); } catch (e) { console.log(e.stack); }
|
||||
});
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
ctx.ws.onopen = () => resolve(ctx.network);
|
||||
});
|
||||
};
|
||||
|
||||
return { connect: connect };
|
||||
});
|
||||
@@ -1342,6 +1342,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
if (msg[0] !== 0 && msg[1] !== 'ACK') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg[2] === 'IDENT' && msg[1] === '') {
|
||||
socket.uid = msg[3];
|
||||
webChannel.myID = msg[3];
|
||||
@@ -1401,7 +1402,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
// Trigger onJoining() when another user is joining the channel
|
||||
// Register the user in the list of peers in the channel
|
||||
if (webChannel.peers.length === 0 && msg[1].length === 16) {
|
||||
// We've just catched the history keeper
|
||||
// We've just catched the history keeper (16 characters length name)
|
||||
history_keeper = msg[1];
|
||||
webChannel.hc = history_keeper;
|
||||
}
|
||||
|
||||
+54
-102
@@ -17,10 +17,11 @@
|
||||
window.Reflect = { has: (x,y) => { return (y in x); } };
|
||||
define([
|
||||
'/common/messages.js',
|
||||
'/common/netflux.js',
|
||||
'/common/netflux-client.js',
|
||||
'/common/crypto.js',
|
||||
'/common/toolbar.js',
|
||||
'/_socket/text-patcher.js',
|
||||
'/common/es6-promise.min.js',
|
||||
'/common/chainpad.js',
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
], function (Messages, Netflux, Crypto, Toolbar, TextPatcher) {
|
||||
@@ -75,7 +76,6 @@ define([
|
||||
function (config)
|
||||
{
|
||||
var websocketUrl = config.websocketURL;
|
||||
var webrtcUrl = config.webrtcURL;
|
||||
var userName = config.userName;
|
||||
var channel = config.channel;
|
||||
var chanKey = config.cryptKey;
|
||||
@@ -122,25 +122,20 @@ define([
|
||||
content.length + ':' + content;
|
||||
};
|
||||
|
||||
var onPeerMessage = function(toId, type, wc) {
|
||||
if(type === 6) {
|
||||
messagesHistory.forEach(function(msg) {
|
||||
wc.sendTo(toId, '1:y'+msg);
|
||||
});
|
||||
wc.sendTo(toId, '0');
|
||||
}
|
||||
};
|
||||
|
||||
var whoami = new RegExp(userName.replace(/[\/\+]/g, function (c) {
|
||||
return '\\' +c;
|
||||
}));
|
||||
|
||||
var onMessage = function(peer, msg, wc) {
|
||||
var onMessage = function(peer, msg, wc, network) {
|
||||
|
||||
if(msg === 0 || msg === '0') {
|
||||
onReady(wc);
|
||||
var hc = (wc && wc.history_keeper) ? wc.history_keeper : null;
|
||||
if(wc && (msg === 0 || msg === '0')) {
|
||||
onReady(wc, network);
|
||||
return;
|
||||
}
|
||||
else if (peer === hc){
|
||||
msg = JSON.parse(msg)[4];
|
||||
}
|
||||
var message = chainpadAdapter.msgIn(peer, msg);
|
||||
|
||||
verbose(message);
|
||||
@@ -176,8 +171,10 @@ define([
|
||||
users: []
|
||||
};
|
||||
var onJoining = function(peer) {
|
||||
if(peer.length !== 32) { return; }
|
||||
var list = userList.users;
|
||||
if(list.indexOf(peer) === -1) {
|
||||
var index = list.indexOf(peer);
|
||||
if(index === -1) {
|
||||
userList.users.push(peer);
|
||||
}
|
||||
userList.onChange();
|
||||
@@ -216,7 +213,7 @@ define([
|
||||
if(parsed.content[0] === 4) { // PING message from Chainpad
|
||||
parsed.content[0] = 5;
|
||||
onMessage('', '1:y'+mkMessage(parsed.user, parsed.channelId, parsed.content));
|
||||
wc.sendPing();
|
||||
// wc.sendPing();
|
||||
return;
|
||||
}
|
||||
return Crypto.encrypt(msg, cryptKey);
|
||||
@@ -227,20 +224,6 @@ define([
|
||||
key: ''
|
||||
};
|
||||
|
||||
var rtc = true;
|
||||
|
||||
if(!getParameterByName("webrtc") || !webrtcUrl) {
|
||||
rtc = false;
|
||||
options.signaling = websocketUrl;
|
||||
options.topology = 'StarTopologyService';
|
||||
options.protocol = 'WebSocketProtocolService';
|
||||
options.connector = 'WebSocketService';
|
||||
options.openWebChannel = true;
|
||||
}
|
||||
else {
|
||||
options.signaling = webrtcUrl;
|
||||
}
|
||||
|
||||
var createRealtime = function(chan) {
|
||||
return ChainPad.create(userName,
|
||||
passwd,
|
||||
@@ -251,12 +234,12 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
var onReady = function(wc) {
|
||||
var onReady = function(wc, network) {
|
||||
if(config.onInit) {
|
||||
config.onInit({
|
||||
myID: wc.myID,
|
||||
realtime: realtime,
|
||||
webChannel: wc,
|
||||
getLag: network.getLag,
|
||||
userList: userList
|
||||
});
|
||||
}
|
||||
@@ -274,18 +257,21 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
var onOpen = function(wc) {
|
||||
var onOpen = function(wc, network) {
|
||||
channel = wc.id;
|
||||
window.location.hash = channel + '|' + chanKey;
|
||||
|
||||
// Add the existing peers in the userList
|
||||
wc.members.forEach(onJoining);
|
||||
|
||||
// Add the handlers to the WebChannel
|
||||
wc.onmessage = function(peer, msg) { // On receiving message
|
||||
onMessage(peer, msg, wc);
|
||||
};
|
||||
wc.onJoining = onJoining; // On user joining the session
|
||||
wc.onLeaving = onLeaving; // On user leaving the session
|
||||
wc.onPeerMessage = function(peerId, type) {
|
||||
onPeerMessage(peerId, type, wc);
|
||||
};
|
||||
wc.on('message', function (msg, sender) { //Channel msg
|
||||
onMessage(sender, msg, wc, network);
|
||||
});
|
||||
wc.on('join', onJoining);
|
||||
wc.on('leave', onLeaving);
|
||||
|
||||
|
||||
if(config.setMyID) {
|
||||
config.setMyID({
|
||||
myID: wc.myID
|
||||
@@ -299,7 +285,7 @@ define([
|
||||
// Filter messages sent by Chainpad to make it compatible with Netflux
|
||||
message = chainpadAdapter.msgOut(message, wc);
|
||||
if(message) {
|
||||
wc.send(message).then(function() {
|
||||
wc.bcast(message).then(function() {
|
||||
// Send the message back to Chainpad once it is sent to the recipients.
|
||||
onMessage(wc.myID, message);
|
||||
}, function(err) {
|
||||
@@ -311,17 +297,11 @@ define([
|
||||
|
||||
// Get the channel history
|
||||
var hc;
|
||||
if(rtc) {
|
||||
wc.channels.forEach(function (c) { if(!hc) { hc = c; } });
|
||||
if(hc) {
|
||||
wc.getHistory(hc.peerID);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO : Improve WebSocket service to use the latest Netflux's API
|
||||
wc.peers.forEach(function (p) { if (!hc || p.linkQuality > hc.linkQuality) { hc = p; } });
|
||||
hc.send(JSON.stringify(['GET_HISTORY', wc.id]));
|
||||
}
|
||||
wc.members.forEach(function (p) {
|
||||
if (p.length === 16) { hc = p; }
|
||||
});
|
||||
wc.history_keeper = hc;
|
||||
if (hc) { network.sendto(hc, JSON.stringify(['GET_HISTORY', wc.id])); }
|
||||
|
||||
|
||||
toReturn.patchText = TextPatcher.create({
|
||||
@@ -331,58 +311,30 @@ define([
|
||||
realtime.start();
|
||||
};
|
||||
|
||||
var createRTCChannel = function () {
|
||||
// Check if the WebRTC channel exists and create it if necessary
|
||||
var webchannel = Netflux.create();
|
||||
webchannel.openForJoining(options).then(function(data) {
|
||||
onOpen(webchannel);
|
||||
onReady(webchannel);
|
||||
}, function(error) {
|
||||
warn(error);
|
||||
});
|
||||
};
|
||||
var findChannelById = function(webChannels, channelId) {
|
||||
var webChannel;
|
||||
webChannels.forEach(function(chan) {
|
||||
if(chan.id == channelId) { webChannel = chan; return;}
|
||||
});
|
||||
return webChannel;
|
||||
}
|
||||
|
||||
var joinChannel = function() {
|
||||
// Connect to the WebSocket/WebRTC channel
|
||||
Netflux.join(channel, options).then(function(wc) {
|
||||
onOpen(wc);
|
||||
}, function(error) {
|
||||
if(rtc && error.code === 1008) {// Unexisting RTC channel
|
||||
createRTCChannel();
|
||||
// Connect to the WebSocket channel
|
||||
Netflux.connect(websocketUrl).then(function(network) {
|
||||
network.on('message', function (msg, sender) { // Direct message
|
||||
var wchan = findChannelById(network.webChannels, channel);
|
||||
if(wchan) {
|
||||
onMessage(sender, msg, wchan, network);
|
||||
}
|
||||
else { warn(error); }
|
||||
});
|
||||
};
|
||||
joinChannel();
|
||||
|
||||
var checkConnection = function(wc) {
|
||||
if(wc.channels && wc.channels.size > 0) {
|
||||
var channels = Array.from(wc.channels);
|
||||
var channel = channels[0];
|
||||
|
||||
var socketChecker = setInterval(function () {
|
||||
if (channel.checkSocket(realtime)) {
|
||||
warn("Socket disconnected!");
|
||||
|
||||
recoverableErrorCount += 1;
|
||||
|
||||
if (recoverableErrorCount >= MAX_RECOVERABLE_ERRORS) {
|
||||
warn("Giving up!");
|
||||
realtime.abort();
|
||||
try { channel.close(); } catch (e) { warn(e); }
|
||||
if (config.onAbort) {
|
||||
config.onAbort({
|
||||
socket: channel
|
||||
});
|
||||
}
|
||||
if (socketChecker) { clearInterval(socketChecker); }
|
||||
}
|
||||
} else {
|
||||
// it's working as expected, continue
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
};
|
||||
network.join(channel || null).then(function(wc) {
|
||||
onOpen(wc, network);
|
||||
}, function(error) {
|
||||
console.error(error);
|
||||
})
|
||||
}, function(error) {
|
||||
warn(error);
|
||||
});
|
||||
|
||||
return toReturn;
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ define([
|
||||
userList.forEach(function(user) {
|
||||
if(user !== myUserName) {
|
||||
var data = (userData) ? (userData[user] || null) : null;
|
||||
var userName = (data) ? data.name : null;
|
||||
var userName = (data) ? data.name : user;
|
||||
if(userName) {
|
||||
if(i === 0) list = ' : ';
|
||||
list += userName + ', ';
|
||||
@@ -170,9 +170,9 @@ define([
|
||||
return $container.find('#'+id)[0];
|
||||
};
|
||||
|
||||
var checkLag = function (webChannel, lagElement) {
|
||||
if(typeof webChannel.getLag !== "function") { return; }
|
||||
var lag = webChannel.getLag();
|
||||
var checkLag = function (getLag, lagElement) {
|
||||
if(typeof getLag !== "function") { return; }
|
||||
var lag = getLag();
|
||||
var lagMsg = Messages.lag + ' ';
|
||||
if(lag) {
|
||||
var lagSec = lag/1000;
|
||||
@@ -214,7 +214,7 @@ define([
|
||||
localStorage['CryptPad_RECENTPADS'] = JSON.stringify(out);
|
||||
};
|
||||
|
||||
var create = function ($container, myUserName, realtime, webChannel, userList, config) {
|
||||
var create = function ($container, myUserName, realtime, getLag, userList, config) {
|
||||
var toolbar = createRealtimeToolbar($container);
|
||||
createEscape(toolbar.find('.rtwysiwyg-toolbar-leftside'));
|
||||
var userListElement = createUserList(toolbar.find('.rtwysiwyg-toolbar-leftside'));
|
||||
@@ -223,7 +223,7 @@ define([
|
||||
var userData = config.userData;
|
||||
var changeNameID = config.changeNameID;
|
||||
|
||||
// Check if the suer is allowed to change his name
|
||||
// Check if the user is allowed to change his name
|
||||
if(changeNameID) {
|
||||
// Create the button and update the element containing the user list
|
||||
userListElement = createChangeName($container, userListElement, changeNameID);
|
||||
@@ -253,7 +253,7 @@ define([
|
||||
|
||||
setInterval(function () {
|
||||
if (!connected) { return; }
|
||||
checkLag(webChannel, lagElement);
|
||||
checkLag(getLag, lagElement);
|
||||
}, 3000);
|
||||
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user