diff --git a/client/scripts/network.js b/client/scripts/network.js index efbd601..96dabd1 100644 --- a/client/scripts/network.js +++ b/client/scripts/network.js @@ -1,3 +1,6 @@ +window.URL = window.URL || window.webkitURL; +window.isRtcSupported = !!(window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection); + class ServerConnection { constructor() { @@ -5,7 +8,6 @@ class ServerConnection { Events.on('beforeunload', e => this._disconnect()); Events.on('pagehide', e => this._disconnect()); document.addEventListener('visibilitychange', e => this._onVisibilityChange()); - } _connect() { @@ -40,12 +42,12 @@ class ServerConnection { this.send({ type: 'pong' }); break; default: - console.error('WS: unkown message type', msg) + console.error('WS: unkown message type', msg); } } send(message) { - if (this._socket.readyState !== this._socket.OPEN) return; + if (!this._isConnected()) return; this._socket.send(JSON.stringify(message)); } @@ -118,7 +120,7 @@ class Peer { type: 'header', name: file.name, mime: file.type, - size: file.size, + size: file.size }); this._chunker = new FileChunker(file, chunk => this._send(chunk), @@ -244,6 +246,7 @@ class RTCPeer extends Peer { this._conn = new RTCPeerConnection(RTCPeer.config); this._conn.onicecandidate = e => this._onIceCandidate(e); this._conn.onconnectionstatechange = e => this._onConnectionStateChange(e); + this._conn.oniceconnectionstatechange = e => this._onIceConnectionStateChange(e); } _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) { console.error(error); } @@ -398,8 +411,8 @@ class WSPeer { class FileChunker { constructor(file, onChunk, onPartitionEnd) { - this._chunkSize = 64000; - this._maxPartitionSize = 1e6; + this._chunkSize = 64000; // 64 KB + this._maxPartitionSize = 1e6; // 1 MB this._offset = 0; this._partitionSize = 0; this._file = file; @@ -466,7 +479,7 @@ class FileDigester { this.progress = this._bytesReceived / this._size; if (this._bytesReceived < this._size) return; // we are done - let received = new Blob(this._buffer, { type: this._mime }); + let received = new Blob(this._buffer, { type: this._mime }); let url = URL.createObjectURL(received); this._callback({ name: this._name, @@ -488,20 +501,13 @@ class Events { } } -window.isRtcSupported = !!(window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection); RTCPeer.config = { 'iceServers': [{ - urls: 'stun:stun.stunprotocol.org:3478' - }, { urls: 'stun:stun.l.google.com:19302' }, { - urls: 'turn:turn.bistri.com:80', - credential: 'homeo', - username: 'homeo' - }, { - urls: 'turn:turn.anyfirewall.com:443?transport=tcp', - credential: 'webrtc', - username: 'webrtc' + urls: 'turn:192.158.29.39:3478?transport=tcp', + credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=', + username: '28224511:1379330808' }] } \ No newline at end of file diff --git a/client/scripts/ui.js b/client/scripts/ui.js index 8ef5251..ccb53f8 100644 --- a/client/scripts/ui.js +++ b/client/scripts/ui.js @@ -25,16 +25,16 @@ class PeersUI { } _onPeerLeft(peerId) { - const peer = $(peerId); - if (!peer) return; - peer.remove(); + const $peer = $(peerId); + if (!$peer) return; + $peer.remove(); } _onFileProgress(progress) { const peerId = progress.sender || progress.recipient; - const peer = $(peerId); - if (!peer) return; - peer.ui.setProgress(progress.progress); + const $peer = $(peerId); + if (!$peer) return; + $peer.ui.setProgress(progress.progress); } _clearPeers() { @@ -237,7 +237,7 @@ class ReceiveDialog extends Dialog { this.show(); if (window.isDownloadSupported) return; - $a.target = "_blank"; // fallback + // $a.target = "_blank"; // fallback } _formatFileSize(bytes) { diff --git a/server/index.js b/server/index.js index f231651..4c02151 100644 --- a/server/index.js +++ b/server/index.js @@ -4,9 +4,7 @@ class SnapdropServer { constructor(port) { const WebSocket = require('ws'); - this._wss = new WebSocket.Server({ - port: port - }); + this._wss = new WebSocket.Server({ port: port }); this._wss.on('connection', (socket, request) => this._onConnection(new Peer(socket, request))); this._wss.on('headers', (headers, response) => this._onHeaders(headers, response)); @@ -57,7 +55,6 @@ class SnapdropServer { this._rooms[peer.ip] = {}; } - // console.log(peer.id, ' joined the room', peer.ip); // notify all other peers for (const otherPeerId in this._rooms[peer.ip]) { const otherPeer = this._rooms[peer.ip][otherPeerId]; @@ -97,10 +94,7 @@ class SnapdropServer { // notify all other peers for (const otherPeerId in this._rooms[peer.ip]) { const otherPeer = this._rooms[peer.ip][otherPeerId]; - this._send(otherPeer, { - type: 'peer-left', - peerId: peer.id - }); + this._send(otherPeer, { type: 'peer-left', peerId: peer.id }); } } } @@ -109,7 +103,7 @@ class SnapdropServer { if (!peer) return console.error('undefined peer'); if (this._wss.readyState !== this._wss.OPEN) return console.error('Socket is closed'); message = JSON.stringify(message); - peer.socket.send(message, error => console.log(error)); + peer.socket.send(message, error => error ? console.log(error): ''); } _keepAlive(peer) { @@ -145,24 +139,55 @@ class Peer { // set remote ip - if (request.headers['x-forwarded-for']) - this.ip = request.headers['x-forwarded-for'].split(/\s*,\s*/)[0]; - else - this.ip = request.connection.remoteAddress; + this._setIP(request); + // 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) { this.id = request.peerId; } else { this.id = request.headers.cookie.replace('peerid=', ''); } - // set peer id - // is WebRTC supported ? - this.rtcSupported = request.url.indexOf('webrtc') > -1; - // set name - this.setName(request); - // for keepalive - this.timerId = 0; - this.lastBeat = Date.now(); + } + + toString() { + return `` + } + + _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 + } } // return uuid of form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx @@ -190,28 +215,6 @@ class Peer { } return uuid; }; - - toString() { - return `` - } - - 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); \ No newline at end of file