mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2025-04-20 07:05:05 -04:00
Network fixes
This commit is contained in:
parent
10196cdf33
commit
23e7c04393
5 changed files with 46 additions and 55 deletions
16
README.md
16
README.md
|
@ -1,9 +1,10 @@
|
||||||
# Snapdrop
|
# Snapdrop
|
||||||
|
|
||||||
[Snapdrop](https://snapdrop.net) is a Progressive Web App inspired by Apple's Airdrop.
|
[Snapdrop](https://snapdrop.net): local file sharing in your browser - inspired by Apple's Airdrop.
|
||||||
|
|
||||||
#### Snapdrop is built with the following awesome technologies:
|
#### Snapdrop Version 2 is built with the following awesome technologies:
|
||||||
* Vanilla HTML / JS / CSS
|
* Vanilla HTML5 / ES6 / CSS3
|
||||||
|
* Progressive Web App
|
||||||
* [WebRTC](http://webrtc.org/)
|
* [WebRTC](http://webrtc.org/)
|
||||||
* [WebSockets](http://www.websocket.org/) fallback (iDevices don't support WebRTC)
|
* [WebSockets](http://www.websocket.org/) fallback (iDevices don't support WebRTC)
|
||||||
* [NodeJS](https://nodejs.org/en/)
|
* [NodeJS](https://nodejs.org/en/)
|
||||||
|
@ -24,7 +25,6 @@ It uses a P2P connection if WebRTC is supported by the browser. (WebRTC needs a
|
||||||
|
|
||||||
If WebRTC isn’t supported (Safari, IE) it uses a Web Sockets fallback for the file transfer. The server connects the clients with a stream.
|
If WebRTC isn’t supported (Safari, IE) it uses a Web Sockets fallback for the file transfer. The server connects the clients with a stream.
|
||||||
|
|
||||||
|
|
||||||
##### What about privacy? Will files be saved on third-party-servers?
|
##### What about privacy? Will files be saved on third-party-servers?
|
||||||
None of your files are ever saved on any server.
|
None of your files are ever saved on any server.
|
||||||
Snapdrop doesn't even use cookies or a database. If you are curious have a look [at the Server](https://github.com/RobinLinus/snapdrop/blob/master/server/ws-server.js).
|
Snapdrop doesn't even use cookies or a database. If you are curious have a look [at the Server](https://github.com/RobinLinus/snapdrop/blob/master/server/ws-server.js).
|
||||||
|
@ -45,12 +45,12 @@ ShareDrop uses WebRTC only and isn't compatible with Safari Browsers. Snapdrop u
|
||||||
|
|
||||||
## Local Development
|
## Local Development
|
||||||
```
|
```
|
||||||
git clone git@github.com:RobinLinus/secret-snapdrop.git
|
git clone git@github.com:RobinLinus/snapdrop.git
|
||||||
cd secret-snapdrop/server
|
cd snapdrop/server
|
||||||
npm install
|
npm install
|
||||||
node index.js
|
node index.js
|
||||||
cd ../client
|
cd ../client
|
||||||
python -m http.server
|
python -m SimpleHTTPServer
|
||||||
```
|
```
|
||||||
|
|
||||||
Now point your browser to http://localhost:8000.
|
Now point your browser to http://localhost:8000.
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
class ServerConnection {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Connection {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class WSConnection extends Connection {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class RTCConnection extends Connection {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Peer {
|
|
||||||
|
|
||||||
constructor(serverConnection) {
|
|
||||||
this._ws = new WSConnection(serverConnection);
|
|
||||||
this._rtc = new RTCConnection(serverConnection);
|
|
||||||
this._fileReceiver = new FileReceiver(this);
|
|
||||||
this._fileSender = new FileSender(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
send(message) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Peers {
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,12 +3,14 @@ class ServerConnection {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._connect();
|
this._connect();
|
||||||
Events.on('beforeunload', e => this._disconnect(), false);
|
Events.on('beforeunload', e => this._disconnect(), false);
|
||||||
|
Events.on('pagehide', e => this._disconnect(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_connect() {
|
_connect() {
|
||||||
|
if (this._isConnected()) return;
|
||||||
const ws = new WebSocket(this._endpoint());
|
const ws = new WebSocket(this._endpoint());
|
||||||
ws.binaryType = 'arraybuffer';
|
ws.binaryType = 'arraybuffer';
|
||||||
ws.onopen = e => console.log('WS: server connection opened');
|
ws.onopen = e => console.log('WS: server connected');
|
||||||
ws.onmessage = e => this._onMessage(e.data);
|
ws.onmessage = e => this._onMessage(e.data);
|
||||||
ws.onclose = e => this._onDisconnect();
|
ws.onclose = e => this._onDisconnect();
|
||||||
ws.onerror = e => console.error(e);
|
ws.onerror = e => console.error(e);
|
||||||
|
@ -16,6 +18,10 @@ class ServerConnection {
|
||||||
clearTimeout(this._reconnectTimer);
|
clearTimeout(this._reconnectTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_isConnected() {
|
||||||
|
return this._socket && this._socket.readyState === this._socket.OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
_onMessage(msg) {
|
_onMessage(msg) {
|
||||||
msg = JSON.parse(msg);
|
msg = JSON.parse(msg);
|
||||||
console.log('WS:', msg);
|
console.log('WS:', msg);
|
||||||
|
@ -224,7 +230,7 @@ class RTCPeer extends Peer {
|
||||||
this._peerId = peerId;
|
this._peerId = peerId;
|
||||||
this._peer = new RTCPeerConnection(RTCPeer.config);
|
this._peer = new RTCPeerConnection(RTCPeer.config);
|
||||||
this._peer.onicecandidate = e => this._onIceCandidate(e);
|
this._peer.onicecandidate = e => this._onIceCandidate(e);
|
||||||
this._peer.onconnectionstatechange = e => console.log('RTC: state changed:', this._peer.connectionState);
|
this._peer.onconnectionstatechange = e => this._onConnectionStateChange(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCaller) {
|
if (isCaller) {
|
||||||
|
@ -237,7 +243,7 @@ class RTCPeer extends Peer {
|
||||||
_createChannel() {
|
_createChannel() {
|
||||||
const channel = this._peer.createDataChannel('data-channel', { reliable: true });
|
const channel = this._peer.createDataChannel('data-channel', { reliable: true });
|
||||||
channel.binaryType = 'arraybuffer';
|
channel.binaryType = 'arraybuffer';
|
||||||
channel.onopen = e => this._onChannelOpened(e)
|
channel.onopen = e => this._onChannelOpened(e);
|
||||||
this._peer.createOffer(d => this._onDescription(d), e => this._onError(e));
|
this._peer.createOffer(d => this._onDescription(d), e => this._onError(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,11 +288,19 @@ class RTCPeer extends Peer {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onChannelClosed() {
|
_onChannelClosed() {
|
||||||
console.log('RTC: channel closed ', this._peerId);
|
console.log('RTC: channel closed', this._peerId);
|
||||||
if (!this.isCaller) return;
|
if (!this.isCaller) return;
|
||||||
this._start(this._peerId, true); // reopen the channel
|
this._start(this._peerId, true); // reopen the channel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onConnectionStateChange(e) {
|
||||||
|
console.log('RTC: state changed:', this._peer.connectionState);
|
||||||
|
switch (this._peer.connectionState) {
|
||||||
|
case 'disconnected': this._onChannelClosed();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_send(message) {
|
_send(message) {
|
||||||
this._channel.send(message);
|
this._channel.send(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,8 +335,8 @@ class Notifications {
|
||||||
constructor() {
|
constructor() {
|
||||||
// Check if the browser supports notifications
|
// Check if the browser supports notifications
|
||||||
if (!('Notification' in window)) return;
|
if (!('Notification' in window)) return;
|
||||||
|
|
||||||
// Check whether notification permissions have already been granted
|
// Check whether notification permissions have already been granted
|
||||||
|
|
||||||
if (Notification.permission !== 'granted') {
|
if (Notification.permission !== 'granted') {
|
||||||
this.$button = $('notification');
|
this.$button = $('notification');
|
||||||
this.$button.removeAttribute('hidden');
|
this.$button.removeAttribute('hidden');
|
||||||
|
@ -358,12 +358,17 @@ class Notifications {
|
||||||
}
|
}
|
||||||
|
|
||||||
_notify(message, body) {
|
_notify(message, body) {
|
||||||
var img = '/images/logo_transparent_128x128.png';
|
const config = {
|
||||||
return new Notification(message, {
|
|
||||||
body: body,
|
body: body,
|
||||||
icon: img,
|
icon: '/images/logo_transparent_128x128.png',
|
||||||
vibrate: [200, 100, 200, 100, 200, 100, 400],
|
vibrate: [200, 100, 200, 100, 200, 100, 400],
|
||||||
});
|
}
|
||||||
|
if (serviceWorker && serviceWorker.showNotification) {
|
||||||
|
// android doesn't support "new Notification" if service worker is installed
|
||||||
|
return serviceWorker.showNotification(message, config);
|
||||||
|
} else {
|
||||||
|
return new Notification(message, config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_messageNotification(message) {
|
_messageNotification(message) {
|
||||||
|
@ -434,10 +439,14 @@ document.copy = text => {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('serviceWorker' in navigator && isProductionEnvironment) {
|
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
navigator.serviceWorker
|
navigator.serviceWorker
|
||||||
.register('/service-worker.js')
|
.register('/service-worker.js')
|
||||||
.then(e => console.log("Service Worker Registered"));
|
.then(serviceWorker => {
|
||||||
|
console.log('Service Worker registered');
|
||||||
|
window.serviceWorker = serviceWorker
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background Animation
|
// Background Animation
|
||||||
|
|
|
@ -34,12 +34,14 @@ class SnapdropServer {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case 'disconnect':
|
case 'disconnect':
|
||||||
this._leaveRoom(sender);
|
this._leaveRoom(sender);
|
||||||
|
break;
|
||||||
case 'pong':
|
case 'pong':
|
||||||
sender.lastBeat = Date.now();
|
sender.lastBeat = Date.now();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// relay message to recipient
|
// relay message to recipient
|
||||||
if (message.to) {
|
if (message.to && this._rooms[sender.ip]) {
|
||||||
const recipientId = message.to; // TODO: sanitize
|
const recipientId = message.to; // TODO: sanitize
|
||||||
const recipient = this._rooms[sender.ip][recipientId];
|
const recipient = this._rooms[sender.ip][recipientId];
|
||||||
delete message.to;
|
delete message.to;
|
||||||
|
@ -84,7 +86,7 @@ class SnapdropServer {
|
||||||
_leaveRoom(peer) {
|
_leaveRoom(peer) {
|
||||||
// delete the peer
|
// delete the peer
|
||||||
this._cancelKeepAlive(peer);
|
this._cancelKeepAlive(peer);
|
||||||
if (!this._rooms[peer.ip]) return;
|
if (!this._rooms[peer.ip] || !this._rooms[peer.ip][peer.id]) return;
|
||||||
|
|
||||||
delete this._rooms[peer.ip][peer.id];
|
delete this._rooms[peer.ip][peer.id];
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue