Merge remote-tracking branch 'origin/dev'

# Conflicts:
#	client/scripts/network.js
#	client/scripts/ui.js
#	server/index.js
This commit is contained in:
RobinLinus 2018-10-09 15:47:57 +02:00
commit 983a2d116b
3 changed files with 76 additions and 67 deletions

View file

@ -1,3 +1,6 @@
window.URL = window.URL || window.webkitURL;
window.isRtcSupported = !!(window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection);
class ServerConnection { class ServerConnection {
constructor() { constructor() {
@ -5,7 +8,6 @@ class ServerConnection {
Events.on('beforeunload', e => this._disconnect()); Events.on('beforeunload', e => this._disconnect());
Events.on('pagehide', e => this._disconnect()); Events.on('pagehide', e => this._disconnect());
document.addEventListener('visibilitychange', e => this._onVisibilityChange()); document.addEventListener('visibilitychange', e => this._onVisibilityChange());
} }
_connect() { _connect() {
@ -40,12 +42,12 @@ class ServerConnection {
this.send({ type: 'pong' }); this.send({ type: 'pong' });
break; break;
default: default:
console.error('WS: unkown message type', msg) console.error('WS: unkown message type', msg);
} }
} }
send(message) { send(message) {
if (this._socket.readyState !== this._socket.OPEN) return; if (!this._isConnected()) return;
this._socket.send(JSON.stringify(message)); this._socket.send(JSON.stringify(message));
} }
@ -118,7 +120,7 @@ class Peer {
type: 'header', type: 'header',
name: file.name, name: file.name,
mime: file.type, mime: file.type,
size: file.size, size: file.size
}); });
this._chunker = new FileChunker(file, this._chunker = new FileChunker(file,
chunk => this._send(chunk), chunk => this._send(chunk),
@ -244,6 +246,7 @@ class RTCPeer extends Peer {
this._conn = new RTCPeerConnection(RTCPeer.config); this._conn = new RTCPeerConnection(RTCPeer.config);
this._conn.onicecandidate = e => this._onIceCandidate(e); this._conn.onicecandidate = e => this._onIceCandidate(e);
this._conn.onconnectionstatechange = e => this._onConnectionStateChange(e); this._conn.onconnectionstatechange = e => this._onConnectionStateChange(e);
this._conn.oniceconnectionstatechange = e => this._onIceConnectionStateChange(e);
} }
_openChannel() { _openChannel() {
@ -305,6 +308,16 @@ class RTCPeer extends Peer {
} }
} }
_onIceConnectionStateChange() {
switch (this._conn.iceConnectionState) {
case 'failed':
console.error('ICE Gathering failed');
break;
default:
console.log('ICE Gathering', this._conn.iceConnectionState);
}
}
_onError(error) { _onError(error) {
console.error(error); console.error(error);
} }
@ -398,8 +411,8 @@ class WSPeer {
class FileChunker { class FileChunker {
constructor(file, onChunk, onPartitionEnd) { constructor(file, onChunk, onPartitionEnd) {
this._chunkSize = 64000; this._chunkSize = 64000; // 64 KB
this._maxPartitionSize = 1e6; this._maxPartitionSize = 1e6; // 1 MB
this._offset = 0; this._offset = 0;
this._partitionSize = 0; this._partitionSize = 0;
this._file = file; this._file = file;
@ -488,20 +501,13 @@ class Events {
} }
} }
window.isRtcSupported = !!(window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection);
RTCPeer.config = { RTCPeer.config = {
'iceServers': [{ 'iceServers': [{
urls: 'stun:stun.stunprotocol.org:3478'
}, {
urls: 'stun:stun.l.google.com:19302' urls: 'stun:stun.l.google.com:19302'
}, { }, {
urls: 'turn:turn.bistri.com:80', urls: 'turn:192.158.29.39:3478?transport=tcp',
credential: 'homeo', credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: 'homeo' username: '28224511:1379330808'
}, {
urls: 'turn:turn.anyfirewall.com:443?transport=tcp',
credential: 'webrtc',
username: 'webrtc'
}] }]
} }

View file

@ -25,16 +25,16 @@ class PeersUI {
} }
_onPeerLeft(peerId) { _onPeerLeft(peerId) {
const peer = $(peerId); const $peer = $(peerId);
if (!peer) return; if (!$peer) return;
peer.remove(); $peer.remove();
} }
_onFileProgress(progress) { _onFileProgress(progress) {
const peerId = progress.sender || progress.recipient; const peerId = progress.sender || progress.recipient;
const peer = $(peerId); const $peer = $(peerId);
if (!peer) return; if (!$peer) return;
peer.ui.setProgress(progress.progress); $peer.ui.setProgress(progress.progress);
} }
_clearPeers() { _clearPeers() {
@ -237,7 +237,7 @@ class ReceiveDialog extends Dialog {
this.show(); this.show();
if (window.isDownloadSupported) return; if (window.isDownloadSupported) return;
$a.target = "_blank"; // fallback // $a.target = "_blank"; // fallback
} }
_formatFileSize(bytes) { _formatFileSize(bytes) {

View file

@ -4,9 +4,7 @@ class SnapdropServer {
constructor(port) { constructor(port) {
const WebSocket = require('ws'); const WebSocket = require('ws');
this._wss = new WebSocket.Server({ this._wss = new WebSocket.Server({ port: port });
port: port
});
this._wss.on('connection', (socket, request) => this._onConnection(new Peer(socket, request))); this._wss.on('connection', (socket, request) => this._onConnection(new Peer(socket, request)));
this._wss.on('headers', (headers, response) => this._onHeaders(headers, response)); this._wss.on('headers', (headers, response) => this._onHeaders(headers, response));
@ -57,7 +55,6 @@ class SnapdropServer {
this._rooms[peer.ip] = {}; this._rooms[peer.ip] = {};
} }
// console.log(peer.id, ' joined the room', peer.ip);
// notify all other peers // notify all other peers
for (const otherPeerId in this._rooms[peer.ip]) { for (const otherPeerId in this._rooms[peer.ip]) {
const otherPeer = this._rooms[peer.ip][otherPeerId]; const otherPeer = this._rooms[peer.ip][otherPeerId];
@ -97,10 +94,7 @@ class SnapdropServer {
// notify all other peers // notify all other peers
for (const otherPeerId in this._rooms[peer.ip]) { for (const otherPeerId in this._rooms[peer.ip]) {
const otherPeer = this._rooms[peer.ip][otherPeerId]; const otherPeer = this._rooms[peer.ip][otherPeerId];
this._send(otherPeer, { this._send(otherPeer, { type: 'peer-left', peerId: peer.id });
type: 'peer-left',
peerId: peer.id
});
} }
} }
} }
@ -109,7 +103,7 @@ class SnapdropServer {
if (!peer) return console.error('undefined peer'); if (!peer) return console.error('undefined peer');
if (this._wss.readyState !== this._wss.OPEN) return console.error('Socket is closed'); if (this._wss.readyState !== this._wss.OPEN) return console.error('Socket is closed');
message = JSON.stringify(message); message = JSON.stringify(message);
peer.socket.send(message, error => console.log(error)); peer.socket.send(message, error => error ? console.log(error): '');
} }
_keepAlive(peer) { _keepAlive(peer) {
@ -145,24 +139,55 @@ class Peer {
// set remote ip // set remote ip
if (request.headers['x-forwarded-for']) this._setIP(request);
this.ip = request.headers['x-forwarded-for'].split(/\s*,\s*/)[0];
else
this.ip = request.connection.remoteAddress;
// set peer id
this._setPeerId(request)
// is WebRTC supported ?
this.rtcSupported = request.url.indexOf('webrtc') > -1;
// set name
this._setName(request);
// for keepalive
this.timerId = 0;
this.lastBeat = Date.now();
}
_setIP(request) {
if (request.headers['x-forwarded-for']) {
this.ip = request.headers['x-forwarded-for'].split(/\s*,\s*/)[0];
} else {
this.ip = request.connection.remoteAddress;
}
}
_setPeerId(request) {
if (request.peerId) { if (request.peerId) {
this.id = request.peerId; this.id = request.peerId;
} else { } else {
this.id = request.headers.cookie.replace('peerid=', ''); this.id = request.headers.cookie.replace('peerid=', '');
} }
// set peer id }
// is WebRTC supported ?
this.rtcSupported = request.url.indexOf('webrtc') > -1; toString() {
// set name return `<Peer id=${this.id} ip=${this.ip} rtcSupported=${this.rtcSupported}>`
this.setName(request); }
// for keepalive
this.timerId = 0; _setName(req) {
this.lastBeat = Date.now(); var ua = parser(req.headers['user-agent']);
this.name = {
model: ua.device.model,
os: ua.os.name,
browser: ua.browser.name,
type: ua.device.type
};
}
getInfo() {
return {
id: this.id,
name: this.name,
rtcSupported: this.rtcSupported
}
} }
// return uuid of form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx // return uuid of form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
@ -190,28 +215,6 @@ class Peer {
} }
return uuid; return uuid;
}; };
toString() {
return `<Peer id=${this.id} ip=${this.ip} rtcSupported=${this.rtcSupported}>`
}
setName(req) {
var ua = parser(req.headers['user-agent']);
this.name = {
model: ua.device.model,
os: ua.os.name,
browser: ua.browser.name,
type: ua.device.type
};
}
getInfo() {
return {
id: this.id,
name: this.name,
rtcSupported: this.rtcSupported
}
}
} }
const server = new SnapdropServer(process.env.PORT || 3000); const server = new SnapdropServer(process.env.PORT || 3000);