Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • sweng-group-15/liowebrtc
1 result
Show changes
Commits on Source (5)
......@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
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 _wildemitter = require('wildemitter');
......@@ -104,13 +106,17 @@ var LioWebRTC = function (_WildEmitter) {
var peers = self.webrtc.getPeers(message.from, message.roomType);
var totalPeers = self.webrtc.getPeers().length;
var peer = void 0;
if (message.type === 'offer') {
if (peers.length) {
peers.forEach(function (p) {
if (p.sid === message.sid) peer = p;
});
// if (!peer) peer = peers[0]; // fallback for old protocol versions
peers.forEach(function (p) {
if (p !== peer) {
p.end(false);
totalPeers--;
}
});
}
if (_this.config.dataOnly && _this.config.constraints.maxPeers > 0 && totalPeers >= _this.config.constraints.maxPeers) {
return;
......@@ -350,6 +356,8 @@ var LioWebRTC = function (_WildEmitter) {
value: function connectToRandomPeer() {
var _this2 = this;
if (!this.connection) return;
this.getClients(function (err, clients) {
var ids = Object.keys(clients).filter(function (c) {
return !(_this2.unconnectivePeers[c] === true || c === _this2.id || (0, _PeerOptimizer.isNeighbor)(_this2.id, c));
......@@ -413,6 +421,8 @@ var LioWebRTC = function (_WildEmitter) {
}, {
key: 'disconnect',
value: function disconnect() {
if (!this.connection) return;
this.connection.disconnect();
delete this.connection;
}
......@@ -490,7 +500,6 @@ var LioWebRTC = function (_WildEmitter) {
var peer = void 0;
_this5.roomCount = Object.keys(roomDescription.clients).length;
// console.log(roomDescription);
_this5.id = roomDescription.you;
(0, _PeerOptimizer.addNode)(_this5.id);
_this5.unconnectivePeers[_this5.id] = true;
......@@ -507,27 +516,49 @@ var LioWebRTC = function (_WildEmitter) {
client = roomDescription.clients[id];
for (type in client) {
if (type !== 'turnservers' && client[type]) {
console.log('Received peer info about', id, 'on room join');
var peerCount = _this5.webrtc.getPeers().length;
if (_this5.config.dataOnly && _this5.config.constraints.maxPeers > 0 && (peerCount >= _this5.config.constraints.minPeers || peerCount >= _this5.config.constraints.maxPeers)) {
return;
}
peer = self.webrtc.createPeer({
id: id,
type: type,
enableDataChannels: self.config.enableDataChannels && type !== 'screen',
receiveMedia: {
offerToReceiveAudio: type !== 'screen' && !_this5.config.dataOnly && _this5.config.receiveMedia.offerToReceiveAudio ? 1 : 0,
offerToReceiveVideo: !_this5.config.dataOnly && self.config.receiveMedia.offerToReceiveVideo ? 1 : 0
},
iceServers: self.webrtc.config.peerConnectionConfig.iceServers.concat(client.turnservers)
});
if (_this5.config.dataOnly && _this5.config.constraints.maxPeers > 0) {
_this5.sendPing(peer, peer.id, true);
} else {
peer.start();
_this5.emit('createdPeer', peer);
}
var _ret = function () {
console.log('Received peer info about', id, 'on room join');
var peerCount = _this5.webrtc.getPeers().length;
var peers = self.webrtc.getPeers(id, type);
var backoff = false;
peers.forEach(function (p) {
console.log('Peer with same ID in state', p.pc.pc.iceConnectionState, 'found');
if (p.pc.pc.iceConnectionState == 'new' || p.pc.pc.iceConnectionState == 'checking') {
backoff = true;
return;
}
p.end(false);
peerCount--;
});
if (backoff) {
return {
v: void 0
};
}
if (_this5.config.dataOnly && _this5.config.constraints.maxPeers > 0 && (peerCount >= _this5.config.constraints.minPeers || peerCount >= _this5.config.constraints.maxPeers)) {
return {
v: void 0
};
}
peer = self.webrtc.createPeer({
id: id,
type: type,
enableDataChannels: self.config.enableDataChannels && type !== 'screen',
receiveMedia: {
offerToReceiveAudio: type !== 'screen' && !_this5.config.dataOnly && _this5.config.receiveMedia.offerToReceiveAudio ? 1 : 0,
offerToReceiveVideo: !_this5.config.dataOnly && self.config.receiveMedia.offerToReceiveVideo ? 1 : 0
},
iceServers: self.webrtc.config.peerConnectionConfig.iceServers.concat(client.turnservers)
});
if (_this5.config.dataOnly && _this5.config.constraints.maxPeers > 0) {
_this5.sendPing(peer, peer.id, true);
} else {
peer.start();
_this5.emit('createdPeer', peer);
}
}();
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
}
}
}
......@@ -607,31 +638,55 @@ var LioWebRTC = function (_WildEmitter) {
}, {
key: 'connectToPeer',
value: function connectToPeer(peerId, client) {
var _this7 = this;
var type = void 0;
var peer = void 0;
for (type in client) {
if (type !== 'turnservers' && client[type]) {
console.log('Connecting to random peer', peerId);
var peerCount = this.webrtc.getPeers().length;
if (this.config.constraints.maxPeers > 0 && peerCount >= this.config.constraints.maxPeers) {
return;
}
peer = this.webrtc.createPeer({
id: peerId,
type: type,
enableDataChannels: this.config.enableDataChannels && type !== 'screen',
receiveMedia: {
offerToReceiveAudio: type !== 'screen' && !this.config.dataOnly && this.config.receiveMedia.offerToReceiveAudio ? 1 : 0,
offerToReceiveVideo: !this.config.dataOnly && this.config.receiveMedia.offerToReceiveVideo ? 1 : 0
},
iceServers: self.webrtc.config.peerConnectionConfig.iceServers.concat(client.turnservers)
});
if (this.config.dataOnly && this.config.constraints.maxPeers > 0) {
this.sendPing(peer, peerId, true);
} else {
peer.start();
this.emit('createdPeer', peer);
}
var _ret2 = function () {
console.log('Connecting to peer', peerId);
var peerCount = _this7.webrtc.getPeers().length;
var peers = _this7.webrtc.getPeers(peerId, type);
var backoff = false;
peers.forEach(function (p) {
console.log('Peer with same ID in state', p.pc.pc.iceConnectionState, 'found');
if (p.pc.pc.iceConnectionState == 'new' || p.pc.pc.iceConnectionState == 'checking') {
backoff = true;
return;
}
p.end(false);
peerCount--;
});
if (backoff) {
return {
v: void 0
};
}
if (_this7.config.constraints.maxPeers > 0 && peerCount >= _this7.config.constraints.maxPeers) {
return {
v: void 0
};
}
peer = _this7.webrtc.createPeer({
id: peerId,
type: type,
enableDataChannels: _this7.config.enableDataChannels && type !== 'screen',
receiveMedia: {
offerToReceiveAudio: type !== 'screen' && !_this7.config.dataOnly && _this7.config.receiveMedia.offerToReceiveAudio ? 1 : 0,
offerToReceiveVideo: !_this7.config.dataOnly && _this7.config.receiveMedia.offerToReceiveVideo ? 1 : 0
},
iceServers: _this7.webrtc.config.peerConnectionConfig.iceServers.concat(client.turnservers)
});
if (_this7.config.dataOnly && _this7.config.constraints.maxPeers > 0) {
_this7.sendPing(peer, peerId, true);
} else {
peer.start();
_this7.emit('createdPeer', peer);
}
}();
if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v;
}
}
}
......
......@@ -22,6 +22,10 @@ var _webrtcsupport = require('./webrtcsupport');
var _webrtcsupport2 = _interopRequireDefault(_webrtcsupport);
var _whatThePack = require('what-the-pack');
var _whatThePack2 = _interopRequireDefault(_whatThePack);
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"); } }
......@@ -30,6 +34,10 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _MessagePack$initiali = _whatThePack2.default.initialize(Math.pow(2, 22)),
encode = _MessagePack$initiali.encode,
decode = _MessagePack$initiali.decode;
function isAllTracksEnded(stream) {
var isAllTracksEnded = true;
stream.getTracks().forEach(function (t) {
......@@ -38,6 +46,11 @@ function isAllTracksEnded(stream) {
return isAllTracksEnded;
}
var protoSend = RTCDataChannel.prototype.send;
RTCDataChannel.prototype.send = function (data) {
protoSend.apply(this, [encode(data)]);
};
var Peer = function (_WildEmitter) {
_inherits(Peer, _WildEmitter);
......@@ -203,7 +216,7 @@ var Peer = function (_WildEmitter) {
this.logger.log('sending via datachannel', channel, messageType, message);
var dc = this.getDataChannel(channel);
if (dc.readyState !== 'open') return false;
dc.send(JSON.stringify(message));
dc.send(message);
return true;
}
......@@ -213,10 +226,11 @@ var Peer = function (_WildEmitter) {
key: '_observeDataChannel',
value: function _observeDataChannel(channel, peer) {
var self = this;
channel.binaryType = 'arraybuffer';
channel.onclose = this.emit.bind(this, 'channelClose', channel, peer);
channel.onerror = this.emit.bind(this, 'channelError', channel, peer);
channel.onmessage = function (event) {
self.emit('channelMessage', self, channel.label, JSON.parse(event.data), channel, event);
self.emit('channelMessage', self, channel.label, decode(_whatThePack2.default.Buffer.from(event.data)), channel, event);
};
channel.onopen = this.emit.bind(this, 'channelOpen', channel, peer);
}
......@@ -282,11 +296,11 @@ var Peer = function (_WildEmitter) {
var emitRemoval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
if (this.closed) return;
this.pc.close();
this.handleStreamRemoved(emitRemoval);
if (emitRemoval) {
this.parent.emit('removedPeer', this);
}
this.pc.close();
this.handleStreamRemoved(emitRemoval);
}
}, {
key: 'handleRemoteStreamAdded',
......@@ -335,10 +349,10 @@ var Peer = function (_WildEmitter) {
});
// override onopen
dc.onopen = function () {
dc.send(JSON.stringify({
dc.send({
size: file.size,
name: file.name
}));
});
sender.send(file, dc);
};
// override onclose
......@@ -348,6 +362,12 @@ var Peer = function (_WildEmitter) {
};
return sender;
}
}, {
key: 'getStats',
value: function getStats(selector) {
// TODO: Use adapter.js to patch this across browsers
return this.pc.pc.getStats(selector);
}
}]);
return Peer;
......
......@@ -96,7 +96,7 @@ var WebRTC = function (_LocalMedia) {
if (peer.enableDataChannels) {
var dc = peer.getDataChannel('liowebrtc');
if (dc.readyState !== 'open') return;
dc.sendDirectlyToAll(JSON.stringify({ type: 'speaking' }));
dc.sendDirectlyToAll({ type: 'speaking' });
}
});
}
......@@ -107,7 +107,7 @@ var WebRTC = function (_LocalMedia) {
if (peer.enableDataChannels) {
var dc = peer.getDataChannel('liowebrtc');
if (dc.readyState !== 'open') return;
dc.sendDirectlyToAll(JSON.stringify({ type: 'stoppedSpeaking' }));
dc.sendDirectlyToAll({ type: 'stoppedSpeaking' });
}
});
}
......@@ -118,7 +118,7 @@ var WebRTC = function (_LocalMedia) {
if (peer.enableDataChannels) {
var dc = peer.getDataChannel('liowebrtc');
if (dc.readyState !== 'open') return;
dc.sendDirectlyToAll(JSON.stringify({ type: 'payload', volume: volume }));
dc.sendDirectlyToAll({ type: 'payload', volume: volume });
}
});
}
......
......@@ -12,6 +12,7 @@
"rtcpeerconnection": "file:../rtcpeerconnection",
"socket.io-client": "^2.3.0",
"webrtc-adapter": "^7.3.0",
"what-the-pack": "^2.0.3",
"wildemitter": "^1.2.0"
},
"devDependencies": {
......
......@@ -60,15 +60,19 @@ class LioWebRTC extends WildEmitter {
connection.on('message', (message) => {
const peers = self.webrtc.getPeers(message.from, message.roomType);
const totalPeers = self.webrtc.getPeers().length;
let totalPeers = self.webrtc.getPeers().length;
let peer;
if (message.type === 'offer') {
if (peers.length) {
peers.forEach((p) => {
if (p.sid === message.sid) peer = p;
});
// if (!peer) peer = peers[0]; // fallback for old protocol versions
peers.forEach((p) => {
if (p !== peer) {
p.end(false);
totalPeers--;
}
});
}
if (this.config.dataOnly && this.config.constraints.maxPeers > 0 && totalPeers >= this.config.constraints.maxPeers) {
return;
......@@ -291,6 +295,9 @@ class LioWebRTC extends WildEmitter {
}
connectToRandomPeer() {
if (!this.connection)
return;
this.getClients((err, clients) => {
const ids = Object.keys(clients).filter(c => !(this.unconnectivePeers[c] === true || c === this.id || isNeighbor(this.id, c)));
if (ids.length) {
......@@ -340,6 +347,9 @@ class LioWebRTC extends WildEmitter {
}
disconnect() {
if (!this.connection)
return;
this.connection.disconnect();
delete this.connection;
}
......@@ -404,7 +414,6 @@ class LioWebRTC extends WildEmitter {
let peer;
this.roomCount = Object.keys(roomDescription.clients).length;
// console.log(roomDescription);
this.id = roomDescription.you;
addNode(this.id);
this.unconnectivePeers[this.id] = true;
......@@ -413,7 +422,21 @@ class LioWebRTC extends WildEmitter {
for (type in client) {
if (type !== 'turnservers' && client[type]) {
console.log('Received peer info about', id, 'on room join')
const peerCount = this.webrtc.getPeers().length;
let peerCount = this.webrtc.getPeers().length;
const peers = self.webrtc.getPeers(id, type);
let backoff = false
peers.forEach((p) => {
console.log('Peer with same ID in state', p.pc.pc.iceConnectionState, 'found')
if (p.pc.pc.iceConnectionState == 'new' || p.pc.pc.iceConnectionState == 'checking') {
backoff = true;
return;
}
p.end(false);
peerCount--;
});
if (backoff) {
return;
}
if (this.config.dataOnly && this.config.constraints.maxPeers > 0 && (peerCount >= this.config.constraints.minPeers || peerCount >= this.config.constraints.maxPeers)) {
return;
}
......@@ -492,8 +515,22 @@ class LioWebRTC extends WildEmitter {
let peer;
for (type in client) {
if (type !== 'turnservers' && client[type]) {
console.log('Connecting to random peer', peerId)
const peerCount = this.webrtc.getPeers().length;
console.log('Connecting to peer', peerId)
let peerCount = this.webrtc.getPeers().length;
const peers = this.webrtc.getPeers(peerId, type);
let backoff = false
peers.forEach((p) => {
console.log('Peer with same ID in state', p.pc.pc.iceConnectionState, 'found')
if (p.pc.pc.iceConnectionState == 'new' || p.pc.pc.iceConnectionState == 'checking') {
backoff = true;
return;
}
p.end(false);
peerCount--;
});
if (backoff) {
return;
}
if (this.config.constraints.maxPeers > 0 && peerCount >= this.config.constraints.maxPeers) {
return;
}
......@@ -505,7 +542,7 @@ class LioWebRTC extends WildEmitter {
offerToReceiveAudio: type !== 'screen' && !this.config.dataOnly && this.config.receiveMedia.offerToReceiveAudio ? 1 : 0,
offerToReceiveVideo: !this.config.dataOnly && this.config.receiveMedia.offerToReceiveVideo ? 1 : 0,
},
iceServers: self.webrtc.config.peerConnectionConfig.iceServers.concat(client.turnservers),
iceServers: this.webrtc.config.peerConnectionConfig.iceServers.concat(client.turnservers),
});
if (this.config.dataOnly && this.config.constraints.maxPeers > 0) {
this.sendPing(peer, peerId, true);
......
......@@ -2,6 +2,9 @@ import PeerConnection from 'rtcpeerconnection';
import WildEmitter from 'wildemitter';
import FileTransfer from 'filetransfer';
import webrtcSupport from './webrtcsupport';
import MessagePack from 'what-the-pack';
const { encode, decode } = MessagePack.initialize(2**22);
function isAllTracksEnded(stream) {
let isAllTracksEnded = true;
......@@ -11,6 +14,11 @@ function isAllTracksEnded(stream) {
return isAllTracksEnded;
}
const protoSend = RTCDataChannel.prototype.send;
RTCDataChannel.prototype.send = function (data) {
protoSend.apply(this, [encode(data)])
};
class Peer extends WildEmitter {
constructor(options) {
super();
......@@ -159,17 +167,18 @@ class Peer extends WildEmitter {
this.logger.log('sending via datachannel', channel, messageType, message);
const dc = this.getDataChannel(channel);
if (dc.readyState !== 'open') return false;
dc.send(JSON.stringify(message));
dc.send(message);
return true;
}
// Internal method registering handlers for a data channel and emitting events on the peer
_observeDataChannel(channel, peer) {
const self = this;
channel.binaryType = 'arraybuffer';
channel.onclose = this.emit.bind(this, 'channelClose', channel, peer);
channel.onerror = this.emit.bind(this, 'channelError', channel, peer);
channel.onmessage = (event) => {
self.emit('channelMessage', self, channel.label, JSON.parse(event.data), channel, event);
self.emit('channelMessage', self, channel.label, decode(MessagePack.Buffer.from(event.data)), channel, event);
};
channel.onopen = this.emit.bind(this, 'channelOpen', channel, peer);
}
......@@ -225,11 +234,11 @@ class Peer extends WildEmitter {
end(emitRemoval = true) {
if (this.closed) return;
this.pc.close();
this.handleStreamRemoved(emitRemoval);
if (emitRemoval) {
this.parent.emit('removedPeer', this);
}
this.pc.close();
this.handleStreamRemoved(emitRemoval);
}
handleRemoteStreamAdded(event) {
......@@ -272,10 +281,10 @@ class Peer extends WildEmitter {
});
// override onopen
dc.onopen = () => {
dc.send(JSON.stringify({
dc.send({
size: file.size,
name: file.name,
}));
});
sender.send(file, dc);
};
// override onclose
......@@ -285,6 +294,11 @@ class Peer extends WildEmitter {
};
return sender;
}
getStats(selector) {
// TODO: Use adapter.js to patch this across browsers
return this.pc.pc.getStats(selector);
}
}
export default Peer;
......@@ -61,7 +61,7 @@ class WebRTC extends LocalMedia {
if (peer.enableDataChannels) {
const dc = peer.getDataChannel('liowebrtc');
if (dc.readyState !== 'open') return;
dc.sendDirectlyToAll(JSON.stringify({ type: 'speaking' }));
dc.sendDirectlyToAll({ type: 'speaking' });
}
});
}
......@@ -72,7 +72,7 @@ class WebRTC extends LocalMedia {
if (peer.enableDataChannels) {
const dc = peer.getDataChannel('liowebrtc');
if (dc.readyState !== 'open') return;
dc.sendDirectlyToAll(JSON.stringify({ type: 'stoppedSpeaking' }));
dc.sendDirectlyToAll({ type: 'stoppedSpeaking' });
}
});
}
......@@ -83,7 +83,7 @@ class WebRTC extends LocalMedia {
if (peer.enableDataChannels) {
const dc = peer.getDataChannel('liowebrtc');
if (dc.readyState !== 'open') return;
dc.sendDirectlyToAll(JSON.stringify({ type: 'payload', volume }));
dc.sendDirectlyToAll({ type: 'payload', volume });
}
});
}
......