174 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
<script src="../../bower_components/peerjs/peer.min.js"></script>
 | 
						|
<link rel="import" href="file-transfer-protocol.html">
 | 
						|
<dom-module id="p2p-network">
 | 
						|
    <template>
 | 
						|
    </template>
 | 
						|
    <script>
 | 
						|
    'use strict';
 | 
						|
    Polymer({
 | 
						|
        is: 'p2p-network',
 | 
						|
        properties: {
 | 
						|
            me: {
 | 
						|
                type: String
 | 
						|
            }
 | 
						|
        },
 | 
						|
        attached: function() {
 | 
						|
            this._connectedPeers = {};
 | 
						|
            this._initCallbacks = [];
 | 
						|
            this._unsendMsgs = {};
 | 
						|
            window.onunload = window.onbeforeunload = function() {
 | 
						|
                if (!!this._peer && !this._peer.destroyed) {
 | 
						|
                    this._peer.destroy();
 | 
						|
                }
 | 
						|
            }.bind(this);
 | 
						|
        },
 | 
						|
        initialize: function() {
 | 
						|
            if (window.isActive) {
 | 
						|
                clearInterval(this.reconnectTimer);
 | 
						|
                this.reconnectTimer = undefined;
 | 
						|
                var options;
 | 
						|
                if (window.debug) {
 | 
						|
                    options = {
 | 
						|
                        host: window.location.hostname,
 | 
						|
                        port: 3002,
 | 
						|
                        path: 'peerjs'
 | 
						|
                    };
 | 
						|
                } else {
 | 
						|
                    options = {
 | 
						|
                        host: 'snapdrop.net',
 | 
						|
                        port: 443,
 | 
						|
                        path: 'peerjs',
 | 
						|
                        secure: true
 | 
						|
                    };
 | 
						|
                }
 | 
						|
                this._peer = new Peer(this.me, options);
 | 
						|
                this._peer.on('open', function(id) {
 | 
						|
                    console.log('My peer ID is: ' + id);
 | 
						|
                    this.set('me', id);
 | 
						|
                    this._peerOpen = true;
 | 
						|
                    this._initCallbacks.forEach(function(cb) {
 | 
						|
                        cb();
 | 
						|
                    });
 | 
						|
                }.bind(this));
 | 
						|
 | 
						|
                this._peer.on('connection', this.connect.bind(this));
 | 
						|
                this._peer.on('error', function(err) {
 | 
						|
                    console.error(err);
 | 
						|
                    //ugly hack to find out error type
 | 
						|
                    if (err.message.indexOf('Could not connect to peer') > -1) {
 | 
						|
                        delete this._connectedPeers[this.peer];
 | 
						|
                        return;
 | 
						|
                    }
 | 
						|
                    if (err.message.indexOf('Lost connection to server') > -1) {
 | 
						|
                        this._peer.destroy();
 | 
						|
                        this._reconnect();
 | 
						|
                        return;
 | 
						|
                    }
 | 
						|
                }.bind(this));
 | 
						|
            }
 | 
						|
        },
 | 
						|
 | 
						|
        connect: function(c) {
 | 
						|
            var peer = c.peer;
 | 
						|
 | 
						|
            if (c.label === 'file') {
 | 
						|
                c.on('data', function(data) {
 | 
						|
                    console.log(data);
 | 
						|
                    var dataView = new Uint8Array(data.file);
 | 
						|
                    var dataBlob = new Blob([dataView]);
 | 
						|
                    this.fire('file-received', {
 | 
						|
                        from: peer,
 | 
						|
                        blob: dataBlob,
 | 
						|
                        name: data.name,
 | 
						|
                    });
 | 
						|
 | 
						|
                }.bind(this));
 | 
						|
            }
 | 
						|
 | 
						|
            if (c.label === 'system') {
 | 
						|
                c.on('data', function(data) {
 | 
						|
                    data.from = peer;
 | 
						|
                    this.fire('system-event', data);
 | 
						|
                }.bind(this));
 | 
						|
            }
 | 
						|
        },
 | 
						|
        connectToPeer: (function() {
 | 
						|
            function request(requestedPeer, callback) {
 | 
						|
                return function() {
 | 
						|
 | 
						|
                    //system messages channel
 | 
						|
                    var s = this._peer.connect(requestedPeer, {
 | 
						|
                        label: 'system'
 | 
						|
                    });
 | 
						|
 | 
						|
                    s.on('open', function() {
 | 
						|
                        this.connect(s);
 | 
						|
                        if (callback) {
 | 
						|
                            callback();
 | 
						|
                        }
 | 
						|
                    }.bind(this));
 | 
						|
                    s.on('error', function(err) {
 | 
						|
                        console.log(err);
 | 
						|
                        if (err.message.indexOf('Connection is not open') > -1) {
 | 
						|
                            console.err('Handle this error!!');
 | 
						|
                        }
 | 
						|
                    });
 | 
						|
 | 
						|
                    //files channel
 | 
						|
                    var f = this._peer.connect(requestedPeer, {
 | 
						|
                        label: 'file',
 | 
						|
                        reliable: true
 | 
						|
                    });
 | 
						|
                    f.on('open', function() {
 | 
						|
                        this.connect(f);
 | 
						|
 | 
						|
                    }.bind(this));
 | 
						|
                    f.on('error', function(err) {
 | 
						|
                        console.log(err);
 | 
						|
                    });
 | 
						|
                };
 | 
						|
            }
 | 
						|
            return function(requestedPeer, callback) {
 | 
						|
                if (this._peer.connections[requestedPeer]) {
 | 
						|
                    callback();
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                if (this._peerOpen) {
 | 
						|
                    request(requestedPeer, callback).bind(this)();
 | 
						|
                } else {
 | 
						|
                    this._initCallbacks.push(request(requestedPeer, callback).bind(this));
 | 
						|
                }
 | 
						|
 | 
						|
            };
 | 
						|
        }()),
 | 
						|
        _sendFile: function(peerId, file) {
 | 
						|
            var conns = this._peer.connections[peerId];
 | 
						|
            if (conns) {
 | 
						|
                conns.forEach(function(conn) {
 | 
						|
                    if (conn.label === 'file') {
 | 
						|
                        conn.send(file);
 | 
						|
                        console.log('send file via WebRTC');
 | 
						|
                    }
 | 
						|
                }.bind(this));
 | 
						|
            }
 | 
						|
        },
 | 
						|
        _sendSystemEvent: function(peerId, msg) {
 | 
						|
            var conns = this._peer.connections[peerId];
 | 
						|
            if (conns) {
 | 
						|
                conns.forEach(function(conn) {
 | 
						|
                    if (conn.label === 'system') {
 | 
						|
                        conn.send(msg);
 | 
						|
                    }
 | 
						|
                }.bind(this));
 | 
						|
            }
 | 
						|
        },
 | 
						|
        _reconnect: function(e) {
 | 
						|
            //try to reconnect after 3s 
 | 
						|
            if (!this.reconnectTimer) {
 | 
						|
                this.reconnectTimer = setInterval(this.initialize.bind(this), 3000);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    });
 | 
						|
    </script>
 | 
						|
</dom-module>
 |