mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2025-04-21 23:36:17 -04:00
Merge remote-tracking branch 'origin/dev'
# Conflicts: # client/scripts/network.js # client/scripts/ui.js # server/index.js
This commit is contained in:
commit
983a2d116b
3 changed files with 76 additions and 67 deletions
|
@ -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'
|
|
||||||
}]
|
}]
|
||||||
}
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
Loading…
Add table
Add a link
Reference in a new issue